summaryrefslogtreecommitdiff
path: root/libtecla-1.4.1/keytab.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtecla-1.4.1/keytab.c')
-rw-r--r--libtecla-1.4.1/keytab.c827
1 files changed, 0 insertions, 827 deletions
diff --git a/libtecla-1.4.1/keytab.c b/libtecla-1.4.1/keytab.c
deleted file mode 100644
index b2bab8b..0000000
--- a/libtecla-1.4.1/keytab.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (c) 2000, 2001 by Martin C. Shepherd.
- *
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, and/or sell copies of the Software, and to permit persons
- * to whom the Software is furnished to do so, provided that the above
- * copyright notice(s) and this permission notice appear in all copies of
- * the Software and that both the above copyright notice(s) and this
- * permission notice appear in supporting documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
- * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
- * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Except as contained in this notice, the name of a copyright holder
- * shall not be used in advertising or otherwise to promote the sale, use
- * or other dealings in this Software without prior written authorization
- * of the copyright holder.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "keytab.h"
-#include "getline.h"
-#include "strngmem.h"
-
-static int _kt_extend_table(KeyTab *kt);
-static int _kt_parse_keybinding_string(const char *keyseq,
- char *binary, int *nc);
-static int _kt_compare_strings(const char *s1, int n1, const char *s2, int n2);
-static void _kt_assign_action(KeySym *sym, KtBinder binder, KtKeyFn *keyfn);
-static char _kt_backslash_escape(const char *string, const char **endp);
-static int _kt_is_emacs_meta(const char *string);
-static int _kt_is_emacs_ctrl(const char *string);
-
-/*.......................................................................
- * Create a new key-binding symbol table.
- *
- * Output:
- * return KeyTab * The new object, or NULL on error.
- */
-KeyTab *_new_KeyTab(void)
-{
- KeyTab *kt; /* The object to be returned */
-/*
- * Allocate the container.
- */
- kt = (KeyTab *) malloc(sizeof(KeyTab));
- if(!kt) {
- fprintf(stderr, "new_KeyTab: Insufficient memory.\n");
- return NULL;
- };
-/*
- * Before attempting any operation that might fail, initialize the
- * container at least up to the point at which it can safely be passed
- * to del_KeyTab().
- */
- kt->size = KT_TABLE_INC;
- kt->nkey = 0;
- kt->table = NULL;
- kt->actions = NULL;
- kt->smem = NULL;
-/*
- * Allocate the table.
- */
- kt->table = (KeySym *) malloc(sizeof(kt->table[0]) * kt->size);
- if(!kt->table) {
- fprintf(stderr, "new_KeyTab: Insufficient memory for table of size %d.\n",
- kt->size);
- return _del_KeyTab(kt);
- };
-/*
- * Allocate a hash table of actions.
- */
- kt->actions = _new_HashTable(NULL, KT_HASH_SIZE, IGNORE_CASE, NULL, 0);
- if(!kt->actions)
- return _del_KeyTab(kt);
-/*
- * Allocate a string allocation object. This allows allocation of
- * small strings without fragmenting the heap.
- */
- kt->smem = _new_StringMem("new_KeyTab", KT_TABLE_INC);
- if(!kt->smem)
- return _del_KeyTab(kt);
- return kt;
-}
-
-/*.......................................................................
- * Delete a KeyTab object.
- *
- * Input:
- * kt KeyTab * The object to be deleted.
- * Output:
- * return KeyTab * The deleted object (always NULL).
- */
-KeyTab *_del_KeyTab(KeyTab *kt)
-{
- if(kt) {
- if(kt->table)
- free(kt->table);
- kt->actions = _del_HashTable(kt->actions);
- kt->smem = _del_StringMem("del_KeyTab", kt->smem, 1);
- free(kt);
- };
- return NULL;
-}
-
-/*.......................................................................
- * Increase the size of the table to accomodate more keys.
- *
- * Input:
- * kt KeyTab * The table to be extended.
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-static int _kt_extend_table(KeyTab *kt)
-{
-/*
- * Attempt to increase the size of the table.
- */
- KeySym *newtab = (KeySym *) realloc(kt->table, sizeof(kt->table[0]) *
- (kt->size + KT_TABLE_INC));
-/*
- * Failed?
- */
- if(!newtab) {
- fprintf(stderr,
- "getline(): Insufficient memory to extend keybinding table.\n");
- return 1;
- };
-/*
- * Install the resized table.
- */
- kt->table = newtab;
- kt->size += KT_TABLE_INC;
- return 0;
-}
-
-/*.......................................................................
- * Add, update or remove a keybinding to the table.
- *
- * Input:
- * kt KeyTab * The table to add the binding to.
- * binder KtBinder The source of the binding.
- * keyseq const char * The key-sequence to bind.
- * action char * The action to associate with the key sequence, or
- * NULL to remove the action associated with the
- * key sequence.
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-int _kt_set_keybinding(KeyTab *kt, KtBinder binder, const char *keyseq,
- const char *action)
-{
- KtKeyFn *keyfn; /* The action function */
-/*
- * Check arguments.
- */
- if(kt==NULL || !keyseq) {
- fprintf(stderr, "kt_set_keybinding: NULL argument(s).\n");
- return 1;
- };
-/*
- * Lookup the function that implements the specified action.
- */
- if(!action) {
- keyfn = 0;
- } else {
- Symbol *sym = _find_HashSymbol(kt->actions, action);
- if(!sym) {
- fprintf(stderr, "getline: Unknown key-binding action: %s\n", action);
- return 1;
- };
- keyfn = (KtKeyFn *) sym->fn;
- };
-/*
- * Record the action in the table.
- */
- return _kt_set_keyfn(kt, binder, keyseq, keyfn);
-}
-
-/*.......................................................................
- * Add, update or remove a keybinding to the table, specifying an action
- * function directly.
- *
- * Input:
- * kt KeyTab * The table to add the binding to.
- * binder KtBinder The source of the binding.
- * keyseq char * The key-sequence to bind.
- * keyfn KtKeyFn * The action function, or NULL to remove any existing
- * action function.
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-int _kt_set_keyfn(KeyTab *kt, KtBinder binder, const char *keyseq,
- KtKeyFn *keyfn)
-{
- const char *kptr; /* A pointer into keyseq[] */
- char *binary; /* The binary version of keyseq[] */
- int nc; /* The number of characters in binary[] */
- int first,last; /* The first and last entries in the table which */
- /* minimally match. */
- int size; /* The size to allocate for the binary string */
-/*
- * Check arguments.
- */
- if(kt==NULL || !keyseq) {
- fprintf(stderr, "kt_set_keybinding: NULL argument(s).\n");
- return 1;
- };
-/*
- * Work out a pessimistic estimate of how much space will be needed
- * for the binary copy of the string, noting that binary meta characters
- * embedded in the input string get split into two characters.
- */
- for(size=0,kptr = keyseq; *kptr; kptr++)
- size += IS_META_CHAR(*kptr) ? 2 : 1;
-/*
- * Allocate a string that has the length of keyseq[].
- */
- binary = _new_StringMemString(kt->smem, size + 1);
- if(!binary) {
- fprintf(stderr,
- "gl_get_line: Insufficient memory to record key sequence.\n");
- return 1;
- };
-/*
- * Convert control and octal character specifications to binary characters.
- */
- if(_kt_parse_keybinding_string(keyseq, binary, &nc)) {
- binary = _del_StringMemString(kt->smem, binary);
- return 1;
- };
-/*
- * Lookup the position in the table at which to insert the binding.
- */
- switch(_kt_lookup_keybinding(kt, binary, nc, &first, &last)) {
-/*
- * If an exact match for the key-sequence is already in the table,
- * simply replace its binding function (or delete the entry if
- * the new binding is 0).
- */
- case KT_EXACT_MATCH:
- if(keyfn) {
- _kt_assign_action(kt->table + first, binder, keyfn);
- } else {
- _del_StringMemString(kt->smem, kt->table[first].keyseq);
- memmove(kt->table + first, kt->table + first + 1,
- (kt->nkey - first - 1) * sizeof(kt->table[0]));
- kt->nkey--;
- };
- binary = _del_StringMemString(kt->smem, binary);
- break;
-/*
- * If an ambiguous match has been found and we are installing a
- * callback, then our new key-sequence would hide all of the ambiguous
- * matches, so we shouldn't allow it.
- */
- case KT_AMBIG_MATCH:
- if(keyfn) {
- fprintf(stderr,
- "getline: Can't bind \"%s\", because it's a prefix of another binding.\n",
- keyseq);
- binary = _del_StringMemString(kt->smem, binary);
- return 1;
- };
- break;
-/*
- * If the entry doesn't exist, create it.
- */
- case KT_NO_MATCH:
-/*
- * Add a new binding?
- */
- if(keyfn) {
- KeySym *sym;
-/*
- * We will need a new entry, extend the table if needed.
- */
- if(kt->nkey + 1 > kt->size) {
- if(_kt_extend_table(kt)) {
- binary = _del_StringMemString(kt->smem, binary);
- return 1;
- };
- };
-/*
- * Make space to insert the new key-sequence before 'last'.
- */
- if(last < kt->nkey) {
- memmove(kt->table + last + 1, kt->table + last,
- (kt->nkey - last) * sizeof(kt->table[0]));
- };
-/*
- * Insert the new binding in the vacated position.
- */
- sym = kt->table + last;
- sym->keyseq = binary;
- sym->nc = nc;
- sym->user_fn = sym->term_fn = sym->norm_fn = sym->keyfn = 0;
- _kt_assign_action(sym, binder, keyfn);
- kt->nkey++;
- };
- break;
- case KT_BAD_MATCH:
- binary = _del_StringMemString(kt->smem, binary);
- return 1;
- break;
- };
- return 0;
-}
-
-/*.......................................................................
- * Perform a min-match lookup of a key-binding.
- *
- * Input:
- * kt KeyTab * The keybinding table to lookup in.
- * binary_keyseq char * The binary key-sequence to lookup.
- * nc int the number of characters in keyseq[].
- * Input/Output:
- * first,last int * If there is an ambiguous or exact match, the indexes
- * of the first and last symbols that minimally match
- * will be assigned to *first and *last respectively.
- * If there is no match, then first and last will
- * bracket the location where the symbol should be
- * inserted.
- *
- * Output:
- * return KtKeyMatch One of the following enumerators:
- * KT_EXACT_MATCH - An exact match was found.
- * KT_AMBIG_MATCH - An ambiguous match was found.
- * KT_NO_MATCH - No match was found.
- * KT_BAD_MATCH - An error occurred while searching.
- */
-KtKeyMatch _kt_lookup_keybinding(KeyTab *kt, const char *binary_keyseq, int nc,
- int *first, int *last)
-{
- int mid; /* The index at which to bisect the table */
- int bot; /* The lowest index of the table not searched yet */
- int top; /* The highest index of the table not searched yet */
- int test; /* The return value of strcmp() */
-/*
- * Check the arguments.
- */
- if(!kt || !binary_keyseq || !first || !last || nc < 0) {
- fprintf(stderr, "kt_lookup_keybinding: NULL argument(s).\n");
- return KT_BAD_MATCH;
- };
-/*
- * Perform a binary search for the key-sequence.
- */
- bot = 0;
- top = kt->nkey - 1;
- while(top >= bot) {
- mid = (top + bot)/2;
- test = _kt_compare_strings(kt->table[mid].keyseq, kt->table[mid].nc,
- binary_keyseq, nc);
- if(test > 0)
- top = mid - 1;
- else if(test < 0)
- bot = mid + 1;
- else {
- *first = *last = mid;
- return KT_EXACT_MATCH;
- };
- };
-/*
- * An exact match wasn't found, but top is the index just below the
- * index where a match would be found, and bot is the index just above
- * where the match ought to be found.
- */
- *first = top;
- *last = bot;
-/*
- * See if any ambiguous matches exist, and if so make *first and *last
- * refer to the first and last matches.
- */
- if(*last < kt->nkey && kt->table[*last].nc > nc &&
- _kt_compare_strings(kt->table[*last].keyseq, nc, binary_keyseq, nc)==0) {
- *first = *last;
- while(*last+1 < kt->nkey && kt->table[*last+1].nc > nc &&
- _kt_compare_strings(kt->table[*last+1].keyseq, nc, binary_keyseq, nc)==0)
- (*last)++;
- return KT_AMBIG_MATCH;
- };
-/*
- * No match.
- */
- return KT_NO_MATCH;
-}
-
-/*.......................................................................
- * Convert a keybinding string into a uniq binary representation.
- *
- * Control characters can be given directly in their binary form,
- * expressed as either ^ or C-, followed by the character, expressed in
- * octal, like \129 or via C-style backslash escapes, with the addition
- * of '\E' to denote the escape key. Similarly, meta characters can be
- * given directly in binary or expressed as M- followed by the character.
- * Meta characters are recorded as two characters in the binary output
- * string, the first being the escape key, and the second being the key
- * that was modified by the meta key. This means that binding to
- * \EA or ^[A or M-A are all equivalent.
- *
- * Input:
- * keyseq char * The key sequence being added.
- * Input/Output:
- * binary char * The binary version of the key sequence will be
- * assigned to binary[], which must have at least
- * as many characters as keyseq[] plus the number
- * of embedded binary meta characters.
- * nc int * The number of characters assigned to binary[]
- * will be recorded in *nc.
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-static int _kt_parse_keybinding_string(const char *keyseq, char *binary,
- int *nc)
-{
- const char *iptr = keyseq; /* Pointer into keyseq[] */
- char *optr = binary; /* Pointer into binary[] */
-/*
- * Parse the input characters until they are exhausted or the
- * output string becomes full.
- */
- while(*iptr) {
-/*
- * Check for special characters.
- */
- switch(*iptr) {
- case '^': /* A control character specification */
-/*
- * Convert the caret expression into the corresponding control
- * character unless no character follows the caret, in which case
- * record a literal caret.
- */
- if(iptr[1]) {
- *optr++ = MAKE_CTRL(iptr[1]);
- iptr += 2;
- } else {
- *optr++ = *iptr++;
- };
- break;
-/*
- * A backslash-escaped character?
- */
- case '\\':
-/*
- * Convert the escape sequence to a binary character.
- */
- *optr++ = _kt_backslash_escape(iptr+1, &iptr);
- break;
-/*
- * Possibly an emacs-style meta character?
- */
- case 'M':
- if(_kt_is_emacs_meta(iptr)) {
- *optr++ = GL_ESC_CHAR;
- iptr += 2;
- } else {
- *optr++ = *iptr++;
- };
- break;
-/*
- * Possibly an emacs-style control character specification?
- */
- case 'C':
- if(_kt_is_emacs_ctrl(iptr)) {
- *optr++ = MAKE_CTRL(iptr[2]);
- iptr += 3;
- } else {
- *optr++ = *iptr++;
- };
- break;
- default:
-
-/*
- * Convert embedded meta characters into an escape character followed
- * by the meta-unmodified character.
- */
- if(IS_META_CHAR(*iptr)) {
- *optr++ = GL_ESC_CHAR;
- *optr++ = META_TO_CHAR(*iptr);
- iptr++;
-/*
- * To allow keysequences that start with printable characters to
- * be distinguished from the cursor-key keywords, prepend a backslash
- * to the former. This same operation is performed in gl_interpret_char()
- * before looking up a keysequence that starts with a printable character.
- */
- } else if(iptr==keyseq && !IS_CTRL_CHAR(*iptr) &&
- strcmp(keyseq, "up") != 0 && strcmp(keyseq, "down") != 0 &&
- strcmp(keyseq, "left") != 0 && strcmp(keyseq, "right") != 0) {
- *optr++ = '\\';
- *optr++ = *iptr++;
- } else {
- *optr++ = *iptr++;
- };
- };
- };
-/*
- * How many characters were placed in the output array?
- */
- *nc = optr - binary;
- return 0;
-}
-
-/*.......................................................................
- * Add, remove or modify an action.
- *
- * Input:
- * kt KeyTab * The key-binding table.
- * action char * The name of the action.
- * fn KtKeyFn * The function that implements the action, or NULL
- * to remove an existing action.
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-int _kt_set_action(KeyTab *kt, const char *action, KtKeyFn *fn)
-{
- Symbol *sym; /* The symbol table entry of the action */
-/*
- * Check the arguments.
- */
- if(!kt || !action) {
- fprintf(stderr, "kt_set_action: NULL argument(s).\n");
- return 1;
- };
-/*
- * If no function was provided, delete an existing action.
- */
- if(!fn) {
- sym = _del_HashSymbol(kt->actions, action);
- return 0;
- };
-/*
- * If the action already exists, replace its action function.
- */
- sym = _find_HashSymbol(kt->actions, action);
- if(sym) {
- sym->fn = (void (*)(void))fn;
- return 0;
- };
-/*
- * Add a new action.
- */
- if(!_new_HashSymbol(kt->actions, action, 0, (void (*)(void))fn, NULL, 0)) {
- fprintf(stderr, "Insufficient memory to record new key-binding action.\n");
- return 1;
- };
- return 0;
-}
-
-/*.......................................................................
- * Compare two strings of specified length which may contain embedded
- * ascii NUL's.
- *
- * Input:
- * s1 char * The first of the strings to be compared.
- * n1 int The length of the string in s1.
- * s2 char * The second of the strings to be compared.
- * n2 int The length of the string in s2.
- * Output:
- * return int < 0 if(s1 < s2)
- * 0 if(s1 == s2)
- * > 0 if(s1 > s2)
- */
-static int _kt_compare_strings(const char *s1, int n1, const char *s2, int n2)
-{
- int i;
-/*
- * Find the first character where the two strings differ.
- */
- for(i=0; i<n1 && i<n2 && s1[i]==s2[i]; i++)
- ;
-/*
- * Did we hit the end of either string before finding a difference?
- */
- if(i==n1 || i==n2) {
- if(n1 == n2)
- return 0;
- else if(n1==i)
- return -1;
- else
- return 1;
- };
-/*
- * Compare the two characters that differed to determine which
- * string is greatest.
- */
- return s1[i] - s2[i];
-}
-
-/*.......................................................................
- * Assign a given action function to a binding table entry.
- *
- * Input:
- * sym KeySym * The binding table entry to be modified.
- * binder KtBinder The source of the binding.
- * keyfn KtKeyFn * The action function.
- */
-static void _kt_assign_action(KeySym *sym, KtBinder binder, KtKeyFn *keyfn)
-{
-/*
- * Record the action according to its source.
- */
- switch(binder) {
- case KTB_USER:
- sym->user_fn = keyfn;
- break;
- case KTB_TERM:
- sym->term_fn = keyfn;
- break;
- case KTB_NORM:
- default:
- sym->norm_fn = keyfn;
- break;
- };
-/*
- * Which of the current set of bindings should be used?
- */
- if(sym->user_fn)
- sym->keyfn = sym->user_fn;
- else if(sym->norm_fn)
- sym->keyfn = sym->norm_fn;
- else
- sym->keyfn = sym->term_fn;
- return;
-}
-
-/*.......................................................................
- * Remove all key bindings that came from a specified source.
- *
- * Input:
- * kt KeyTab * The table of key bindings.
- * binder KtBinder The source of the bindings to be cleared.
- */
-void _kt_clear_bindings(KeyTab *kt, KtBinder binder)
-{
- int oldkey; /* The index of a key in the original binding table */
- int newkey; /* The index of a key in the updated binding table */
-/*
- * If there is no table, then no bindings exist to be deleted.
- */
- if(!kt)
- return;
-/*
- * Clear bindings of the given source.
- */
- for(oldkey=0; oldkey<kt->nkey; oldkey++)
- _kt_assign_action(kt->table + oldkey, binder, 0);
-/*
- * Delete entries that now don't have a binding from any source.
- */
- newkey = 0;
- for(oldkey=0; oldkey<kt->nkey; oldkey++) {
- KeySym *sym = kt->table + oldkey;
- if(!sym->keyfn) {
- _del_StringMemString(kt->smem, sym->keyseq);
- } else {
- if(oldkey != newkey)
- kt->table[newkey] = *sym;
- newkey++;
- };
- };
-/*
- * Record the number of keys that were kept.
- */
- kt->nkey = newkey;
- return;
-}
-
-/*.......................................................................
- * Translate a backslash escape sequence to a binary character.
- *
- * Input:
- * string const char * The characters that follow the backslash.
- * Input/Output:
- * endp const char ** If endp!=NULL, on return *endp will be made to
- * point to the character in string[] which follows
- * the escape sequence.
- * Output:
- * return char The binary character.
- */
-static char _kt_backslash_escape(const char *string, const char **endp)
-{
- char c; /* The output character */
-/*
- * Is the backslash followed by one or more octal digits?
- */
- switch(*string) {
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- c = strtol(string, (char **)&string, 8);
- break;
- case 'a':
- c = '\a';
- string++;
- break;
- case 'b':
- c = '\b';
- string++;
- break;
- case 'e': case 'E': /* Escape */
- c = GL_ESC_CHAR;
- string++;
- break;
- case 'f':
- c = '\f';
- string++;
- break;
- case 'n':
- c = '\n';
- string++;
- break;
- case 'r':
- c = '\r';
- string++;
- break;
- case 't':
- c = '\t';
- string++;
- break;
- case 'v':
- c = '\v';
- string++;
- break;
- case '\0':
- c = '\\';
- break;
- default:
- c = *string++;
- break;
- };
-/*
- * Report the character which follows the escape sequence.
- */
- if(endp)
- *endp = string;
- return c;
-}
-
-/*.......................................................................
- * Return non-zero if the next two characters are M- and a third character
- * follows. Otherwise return 0.
- *
- * Input:
- * string const char * The sub-string to scan.
- * Output:
- * return int 1 - The next two characters are M- and these
- * are followed by at least one character.
- * 0 - The next two characters aren't M- or no
- * character follows a M- pair.
- */
-static int _kt_is_emacs_meta(const char *string)
-{
- return *string++ == 'M' && *string++ == '-' && *string;
-}
-
-/*.......................................................................
- * Return non-zero if the next two characters are C- and a third character
- * follows. Otherwise return 0.
- *
- * Input:
- * string const char * The sub-string to scan.
- * Output:
- * return int 1 - The next two characters are C- and these
- * are followed by at least one character.
- * 0 - The next two characters aren't C- or no
- * character follows a C- pair.
- */
-static int _kt_is_emacs_ctrl(const char *string)
-{
- return *string++ == 'C' && *string++ == '-' && *string;
-}
-
-/*.......................................................................
- * Merge an array of bindings with existing bindings.
- *
- * Input:
- * kt KeyTab * The table of key bindings.
- * binder KtBinder The source of the bindings.
- * bindings const KtKeyBinding * The array of bindings.
- * n int The number of bindings in bindings[].
- * Output:
- * return int 0 - OK.
- * 1 - Error.
- */
-int _kt_add_bindings(KeyTab *kt, KtBinder binder, const KtKeyBinding *bindings,
- unsigned n)
-{
- int i;
-/*
- * Check the arguments.
- */
- if(!kt || !bindings) {
- fprintf(stderr, "_kt_add_bindings: NULL argument(s).\n");
- return 1;
- };
-/*
- * Install the array of bindings.
- */
- for(i=0; i<n; i++) {
- if(_kt_set_keybinding(kt, binder, bindings[i].keyseq, bindings[i].action))
- return 1;
- };
- return 0;
-}
-