aboutsummaryrefslogtreecommitdiffhomepage
path: root/input.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:11:54 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:11:54 -0800
commit3f16ace6784caab54fb054836ee93902e9701913 (patch)
tree6ae6170f86bd45ce7fd0dae4a4242bb8dc67c505 /input.cpp
parent834ea94eb97d37c65fcbf2fcc3b69303f6fb7e24 (diff)
Initial C++ conversion
Diffstat (limited to 'input.cpp')
-rw-r--r--input.cpp887
1 files changed, 887 insertions, 0 deletions
diff --git a/input.cpp b/input.cpp
new file mode 100644
index 00000000..b0ebc0c6
--- /dev/null
+++ b/input.cpp
@@ -0,0 +1,887 @@
+/** \file input.c
+
+ Functions for reading a character of input from stdin.
+
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_TERMIOS_H
+#include <sys/termios.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#include <unistd.h>
+#include <wchar.h>
+
+#if HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#include <curses.h>
+#endif
+
+
+#if HAVE_TERMIO_H
+#include <termio.h>
+#endif
+
+#if HAVE_TERM_H
+#include <term.h>
+#elif HAVE_NCURSES_TERM_H
+#include <ncurses/term.h>
+#endif
+
+#include <signal.h>
+#include <dirent.h>
+#include <wctype.h>
+
+
+
+#include "fallback.h"
+#include "util.h"
+
+#include "wutil.h"
+#include "reader.h"
+#include "proc.h"
+#include "common.h"
+#include "sanity.h"
+#include "input_common.h"
+#include "input.h"
+#include "parser.h"
+#include "env.h"
+#include "expand.h"
+#include "event.h"
+#include "signal.h"
+
+#include "output.h"
+#include "intern.h"
+#include "halloc.h"
+#include "halloc_util.h"
+
+/**
+ Add a new terminfo mapping
+*/
+#define TERMINFO_ADD(key) \
+ { \
+ terminfo_mapping_t *m = halloc( terminfo_mappings, sizeof( terminfo_mapping_t ) ); \
+ m->name = halloc_wcsdup( terminfo_mappings, (L ## #key)+4 ); \
+ m->seq = key; \
+ al_push( terminfo_mappings, m ); \
+ }
+
+
+/**
+ Struct representing a keybinding. Returned by input_get_mappings.
+ */
+typedef struct
+{
+ const wchar_t *seq; /**< Character sequence which generates this event */
+ const wchar_t *command; /**< command that should be evaluated by this mapping */
+
+}
+ input_mapping_t;
+
+/**
+ A struct representing the mapping from a terminfo key name to a terminfo character sequence
+ */
+typedef struct
+{
+ const wchar_t *name; /**< Name of key */
+ const char *seq; /**< Character sequence generated on keypress */
+
+}
+ terminfo_mapping_t;
+
+
+/**
+ Names of all the input functions supported
+*/
+static const wchar_t *name_arr[] =
+{
+ L"beginning-of-line",
+ L"end-of-line",
+ L"forward-char",
+ L"backward-char",
+ L"forward-word",
+ L"backward-word",
+ L"history-search-backward",
+ L"history-search-forward",
+ L"delete-char",
+ L"backward-delete-char",
+ L"kill-line",
+ L"yank",
+ L"yank-pop",
+ L"complete",
+ L"beginning-of-history",
+ L"end-of-history",
+ L"backward-kill-line",
+ L"kill-whole-line",
+ L"kill-word",
+ L"backward-kill-word",
+ L"dump-functions",
+ L"history-token-search-backward",
+ L"history-token-search-forward",
+ L"self-insert",
+ L"null",
+ L"eof",
+ L"vi-arg-digit",
+ L"execute",
+ L"beginning-of-buffer",
+ L"end-of-buffer",
+ L"repaint",
+ L"up-line",
+ L"down-line"
+}
+ ;
+
+/**
+ Description of each supported input function
+*/
+/*
+static const wchar_t *desc_arr[] =
+{
+ L"Move to beginning of line",
+ L"Move to end of line",
+ L"Move forward one character",
+ L"Move backward one character",
+ L"Move forward one word",
+ L"Move backward one word",
+ L"Search backward through list of previous commands",
+ L"Search forward through list of previous commands",
+ L"Delete one character forward",
+ L"Delete one character backward",
+ L"Move contents from cursor to end of line to killring",
+ L"Paste contents of killring",
+ L"Rotate to previous killring entry",
+ L"Guess the rest of the next input token",
+ L"Move to first item of history",
+ L"Move to last item of history",
+ L"Clear current line",
+ L"Move contents from beginning of line to cursor to killring",
+ L"Move entire line to killring",
+ L"Move next word to killring",
+ L"Move previous word to killring",
+ L"Write out keybindings",
+ L"Clear entire screen",
+ L"Quit the running program",
+ L"Search backward through list of previous commands for matching token",
+ L"Search forward through list of previous commands for matching token",
+ L"Insert the pressed key",
+ L"Do nothing",
+ L"End of file",
+ L"Repeat command"
+}
+ ;
+*/
+
+/**
+ Internal code for each supported input function
+*/
+static const wchar_t code_arr[] =
+{
+ R_BEGINNING_OF_LINE,
+ R_END_OF_LINE,
+ R_FORWARD_CHAR,
+ R_BACKWARD_CHAR,
+ R_FORWARD_WORD,
+ R_BACKWARD_WORD,
+ R_HISTORY_SEARCH_BACKWARD,
+ R_HISTORY_SEARCH_FORWARD,
+ R_DELETE_CHAR,
+ R_BACKWARD_DELETE_CHAR,
+ R_KILL_LINE,
+ R_YANK,
+ R_YANK_POP,
+ R_COMPLETE,
+ R_BEGINNING_OF_HISTORY,
+ R_END_OF_HISTORY,
+ R_BACKWARD_KILL_LINE,
+ R_KILL_WHOLE_LINE,
+ R_KILL_WORD,
+ R_BACKWARD_KILL_WORD,
+ R_DUMP_FUNCTIONS,
+ R_HISTORY_TOKEN_SEARCH_BACKWARD,
+ R_HISTORY_TOKEN_SEARCH_FORWARD,
+ R_SELF_INSERT,
+ R_NULL,
+ R_EOF,
+ R_VI_ARG_DIGIT,
+ R_EXECUTE,
+ R_BEGINNING_OF_BUFFER,
+ R_END_OF_BUFFER,
+ R_REPAINT,
+ R_UP_LINE,
+ R_DOWN_LINE
+}
+ ;
+
+
+/**
+ Mappings for the current input mode
+*/
+static array_list_t mappings = {0,0,0};
+
+/**
+ List of all terminfo mappings
+ */
+static array_list_t *terminfo_mappings = 0;
+
+
+/**
+ Set to one when the input subsytem has been initialized.
+*/
+static int is_init = 0;
+
+/**
+ Initialize terminfo.
+ */
+static void input_terminfo_init();
+/**
+ Deallocate memory used by terminfo. Or at least try to. Terminfo leaks.
+ */
+static void input_terminfo_destroy();
+
+/**
+ Returns the function description for the given function code.
+*/
+
+void input_mapping_add( const wchar_t *sequence,
+ const wchar_t *command )
+{
+ int i;
+
+ CHECK( sequence, );
+ CHECK( command, );
+
+ // debug( 0, L"Add mapping from %ls to %ls", escape(sequence, 1), escape(command, 1 ) );
+
+
+ for( i=0; i<al_get_count( &mappings); i++ )
+ {
+ input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
+ if( wcscmp( m->seq, sequence ) == 0 )
+ {
+ m->command = intern(command);
+ return;
+ }
+ }
+
+ input_mapping_t *m = malloc( sizeof( input_mapping_t ) );
+ m->seq = intern( sequence );
+ m->command = intern(command);
+ al_push( &mappings, m );
+
+}
+
+/**
+ Handle interruptions to key reading by reaping finshed jobs and
+ propagating the interrupt to the reader.
+*/
+static int interrupt_handler()
+{
+ /*
+ Fire any pending events
+ */
+ event_fire( NULL );
+
+ /*
+ Reap stray processes, including printing exit status messages
+ */
+ if( job_reap( 1 ) )
+ reader_repaint_needed();
+
+ /*
+ Tell the reader an event occured
+ */
+ if( reader_interrupted() )
+ {
+ /*
+ Return 3, i.e. the character read by a Control-C.
+ */
+ return 3;
+ }
+
+ return R_NULL;
+}
+
+int input_init()
+{
+ if( is_init )
+ return 1;
+
+ is_init = 1;
+
+ input_common_init( &interrupt_handler );
+
+ if( setupterm( 0, STDOUT_FILENO, 0) == ERR )
+ {
+ debug( 0, _( L"Could not set up terminal" ) );
+ exit(1);
+ }
+ output_set_term( env_get( L"TERM" ) );
+
+ input_terminfo_init();
+
+ /*
+ If we have no keybindings, add a few simple defaults
+ */
+ if( !al_get_count( &mappings ) )
+ {
+ input_mapping_add( L"", L"self-insert" );
+ input_mapping_add( L"\n", L"execute" );
+ input_mapping_add( L"\t", L"complete" );
+ input_mapping_add( L"\x3", L"commandline \"\"" );
+ input_mapping_add( L"\x4", L"exit" );
+ input_mapping_add( L"\x5", L"bind" );
+ }
+
+ return 1;
+}
+
+void input_destroy()
+{
+ if( !is_init )
+ return;
+
+
+ is_init=0;
+
+ al_foreach( &mappings, &free );
+ al_destroy( &mappings );
+
+ input_common_destroy();
+
+ if( del_curterm( cur_term ) == ERR )
+ {
+ debug( 0, _(L"Error while closing terminfo") );
+ }
+
+ input_terminfo_destroy();
+
+}
+
+/**
+ Perform the action of the specified binding
+*/
+static wint_t input_exec_binding( input_mapping_t *m, const wchar_t *seq )
+{
+ wchar_t code = input_function_get_code( m->command );
+ if( code != -1 )
+ {
+ switch( code )
+ {
+
+ case R_SELF_INSERT:
+ {
+ return seq[0];
+ }
+
+ default:
+ {
+ return code;
+ }
+
+ }
+ }
+ else
+ {
+
+ /*
+ This key sequence is bound to a command, which
+ is sent to the parser for evaluation.
+ */
+ int last_status = proc_get_last_status();
+
+ eval( m->command, 0, TOP );
+
+ proc_set_last_status( last_status );
+
+ /*
+ We still need to return something to the caller, R_NULL
+ tells the reader that no key press needs to be handled,
+ and no repaint is needed.
+
+ Bindings that produce output should emit a R_REPAINT
+ function by calling 'commandline -f repaint' to tell
+ fish that a repaint is in order.
+ */
+
+ return R_NULL;
+
+ }
+}
+
+
+
+/**
+ Try reading the specified function mapping
+*/
+static wint_t input_try_mapping( input_mapping_t *m)
+{
+ int j, k;
+ wint_t c=0;
+
+ /*
+ Check if the actual function code of this mapping is on the stack
+ */
+ c = input_common_readch( 0 );
+ if( c == input_function_get_code( m->command ) )
+ {
+ return input_exec_binding( m, m->seq );
+ }
+ input_unreadch( c );
+
+ if( m->seq != 0 )
+ {
+
+ for( j=0; m->seq[j] != L'\0' &&
+ m->seq[j] == (c=input_common_readch( j>0 )); j++ )
+ ;
+
+ if( m->seq[j] == L'\0' )
+ {
+ return input_exec_binding( m, m->seq );
+ }
+ else
+ {
+ /*
+ Return the read characters
+ */
+ input_unreadch(c);
+ for( k=j-1; k>=0; k-- )
+ {
+ input_unreadch( m->seq[k] );
+ }
+ }
+ }
+ return 0;
+
+}
+
+void input_unreadch( wint_t ch )
+{
+ input_common_unreadch( ch );
+}
+
+wint_t input_readch()
+{
+
+ int i;
+
+ CHECK_BLOCK( R_NULL );
+
+ /*
+ Clear the interrupted flag
+ */
+ reader_interrupted();
+
+ /*
+ Search for sequence in mapping tables
+ */
+
+ while( 1 )
+ {
+ input_mapping_t *generic = 0;
+ for( i=0; i<al_get_count( &mappings); i++ )
+ {
+ input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
+ wint_t res = input_try_mapping( m );
+ if( res )
+ return res;
+
+ if( wcslen( m->seq) == 0 )
+ {
+ generic = m;
+ }
+
+ }
+
+ /*
+ No matching exact mapping, try to find generic mapping.
+ */
+
+ if( generic )
+ {
+ wchar_t arr[2]=
+ {
+ 0,
+ 0
+ }
+ ;
+ arr[0] = input_common_readch(0);
+
+ return input_exec_binding( generic, arr );
+ }
+
+ /*
+ No action to take on specified character, ignore it
+ and move to next one.
+ */
+ input_common_readch( 0 ); }
+}
+
+void input_mapping_get_names( array_list_t *list )
+{
+ int i;
+
+ for( i=0; i<al_get_count( &mappings ); i++ )
+ {
+ input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
+ al_push( list, m->seq );
+ }
+
+}
+
+
+int input_mapping_erase( const wchar_t *sequence )
+{
+ int ok = 0;
+ int i;
+ size_t sz = al_get_count( &mappings );
+
+ for( i=0; i<sz; i++ )
+ {
+ input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
+ if( !wcscmp( sequence, m->seq ) )
+ {
+ if( i != (sz-1 ) )
+ {
+ al_set( &mappings, i, al_get( &mappings, sz -1 ) );
+ }
+ al_truncate( &mappings, sz-1 );
+ ok = 1;
+
+ free( m );
+
+ break;
+
+ }
+
+ }
+
+ return ok;
+
+}
+
+const wchar_t *input_mapping_get( const wchar_t *sequence )
+{
+ int i;
+ size_t sz = al_get_count( &mappings );
+
+ for( i=0; i<sz; i++ )
+ {
+ input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
+ if( !wcscmp( sequence, m->seq ) )
+ {
+ return m->command;
+ }
+ }
+ return 0;
+}
+
+/**
+ Add all terminfo mappings
+ */
+static void input_terminfo_init()
+{
+ terminfo_mappings = al_halloc( 0 );
+
+
+ TERMINFO_ADD(key_a1);
+ TERMINFO_ADD(key_a3);
+ TERMINFO_ADD(key_b2);
+ TERMINFO_ADD(key_backspace);
+ TERMINFO_ADD(key_beg);
+ TERMINFO_ADD(key_btab);
+ TERMINFO_ADD(key_c1);
+ TERMINFO_ADD(key_c3);
+ TERMINFO_ADD(key_cancel);
+ TERMINFO_ADD(key_catab);
+ TERMINFO_ADD(key_clear);
+ TERMINFO_ADD(key_close);
+ TERMINFO_ADD(key_command);
+ TERMINFO_ADD(key_copy);
+ TERMINFO_ADD(key_create);
+ TERMINFO_ADD(key_ctab);
+ TERMINFO_ADD(key_dc);
+ TERMINFO_ADD(key_dl);
+ TERMINFO_ADD(key_down);
+ TERMINFO_ADD(key_eic);
+ TERMINFO_ADD(key_end);
+ TERMINFO_ADD(key_enter);
+ TERMINFO_ADD(key_eol);
+ TERMINFO_ADD(key_eos);
+ TERMINFO_ADD(key_exit);
+ TERMINFO_ADD(key_f0);
+ TERMINFO_ADD(key_f1);
+ TERMINFO_ADD(key_f2);
+ TERMINFO_ADD(key_f3);
+ TERMINFO_ADD(key_f4);
+ TERMINFO_ADD(key_f5);
+ TERMINFO_ADD(key_f6);
+ TERMINFO_ADD(key_f7);
+ TERMINFO_ADD(key_f8);
+ TERMINFO_ADD(key_f9);
+ TERMINFO_ADD(key_f10);
+ TERMINFO_ADD(key_f11);
+ TERMINFO_ADD(key_f12);
+ TERMINFO_ADD(key_f13);
+ TERMINFO_ADD(key_f14);
+ TERMINFO_ADD(key_f15);
+ TERMINFO_ADD(key_f16);
+ TERMINFO_ADD(key_f17);
+ TERMINFO_ADD(key_f18);
+ TERMINFO_ADD(key_f19);
+ TERMINFO_ADD(key_f20);
+ /*
+ I know of no keyboard with more than 20 function keys, so
+ adding the rest here makes very little sense, since it will
+ take up a lot of room in any listings (like tab completions),
+ but with no benefit.
+ */
+ /*
+ TERMINFO_ADD(key_f21);
+ TERMINFO_ADD(key_f22);
+ TERMINFO_ADD(key_f23);
+ TERMINFO_ADD(key_f24);
+ TERMINFO_ADD(key_f25);
+ TERMINFO_ADD(key_f26);
+ TERMINFO_ADD(key_f27);
+ TERMINFO_ADD(key_f28);
+ TERMINFO_ADD(key_f29);
+ TERMINFO_ADD(key_f30);
+ TERMINFO_ADD(key_f31);
+ TERMINFO_ADD(key_f32);
+ TERMINFO_ADD(key_f33);
+ TERMINFO_ADD(key_f34);
+ TERMINFO_ADD(key_f35);
+ TERMINFO_ADD(key_f36);
+ TERMINFO_ADD(key_f37);
+ TERMINFO_ADD(key_f38);
+ TERMINFO_ADD(key_f39);
+ TERMINFO_ADD(key_f40);
+ TERMINFO_ADD(key_f41);
+ TERMINFO_ADD(key_f42);
+ TERMINFO_ADD(key_f43);
+ TERMINFO_ADD(key_f44);
+ TERMINFO_ADD(key_f45);
+ TERMINFO_ADD(key_f46);
+ TERMINFO_ADD(key_f47);
+ TERMINFO_ADD(key_f48);
+ TERMINFO_ADD(key_f49);
+ TERMINFO_ADD(key_f50);
+ TERMINFO_ADD(key_f51);
+ TERMINFO_ADD(key_f52);
+ TERMINFO_ADD(key_f53);
+ TERMINFO_ADD(key_f54);
+ TERMINFO_ADD(key_f55);
+ TERMINFO_ADD(key_f56);
+ TERMINFO_ADD(key_f57);
+ TERMINFO_ADD(key_f58);
+ TERMINFO_ADD(key_f59);
+ TERMINFO_ADD(key_f60);
+ TERMINFO_ADD(key_f61);
+ TERMINFO_ADD(key_f62);
+ TERMINFO_ADD(key_f63);*/
+ TERMINFO_ADD(key_find);
+ TERMINFO_ADD(key_help);
+ TERMINFO_ADD(key_home);
+ TERMINFO_ADD(key_ic);
+ TERMINFO_ADD(key_il);
+ TERMINFO_ADD(key_left);
+ TERMINFO_ADD(key_ll);
+ TERMINFO_ADD(key_mark);
+ TERMINFO_ADD(key_message);
+ TERMINFO_ADD(key_move);
+ TERMINFO_ADD(key_next);
+ TERMINFO_ADD(key_npage);
+ TERMINFO_ADD(key_open);
+ TERMINFO_ADD(key_options);
+ TERMINFO_ADD(key_ppage);
+ TERMINFO_ADD(key_previous);
+ TERMINFO_ADD(key_print);
+ TERMINFO_ADD(key_redo);
+ TERMINFO_ADD(key_reference);
+ TERMINFO_ADD(key_refresh);
+ TERMINFO_ADD(key_replace);
+ TERMINFO_ADD(key_restart);
+ TERMINFO_ADD(key_resume);
+ TERMINFO_ADD(key_right);
+ TERMINFO_ADD(key_save);
+ TERMINFO_ADD(key_sbeg);
+ TERMINFO_ADD(key_scancel);
+ TERMINFO_ADD(key_scommand);
+ TERMINFO_ADD(key_scopy);
+ TERMINFO_ADD(key_screate);
+ TERMINFO_ADD(key_sdc);
+ TERMINFO_ADD(key_sdl);
+ TERMINFO_ADD(key_select);
+ TERMINFO_ADD(key_send);
+ TERMINFO_ADD(key_seol);
+ TERMINFO_ADD(key_sexit);
+ TERMINFO_ADD(key_sf);
+ TERMINFO_ADD(key_sfind);
+ TERMINFO_ADD(key_shelp);
+ TERMINFO_ADD(key_shome);
+ TERMINFO_ADD(key_sic);
+ TERMINFO_ADD(key_sleft);
+ TERMINFO_ADD(key_smessage);
+ TERMINFO_ADD(key_smove);
+ TERMINFO_ADD(key_snext);
+ TERMINFO_ADD(key_soptions);
+ TERMINFO_ADD(key_sprevious);
+ TERMINFO_ADD(key_sprint);
+ TERMINFO_ADD(key_sr);
+ TERMINFO_ADD(key_sredo);
+ TERMINFO_ADD(key_sreplace);
+ TERMINFO_ADD(key_sright);
+ TERMINFO_ADD(key_srsume);
+ TERMINFO_ADD(key_ssave);
+ TERMINFO_ADD(key_ssuspend);
+ TERMINFO_ADD(key_stab);
+ TERMINFO_ADD(key_sundo);
+ TERMINFO_ADD(key_suspend);
+ TERMINFO_ADD(key_undo);
+ TERMINFO_ADD(key_up);
+}
+
+static void input_terminfo_destroy()
+{
+
+ if( terminfo_mappings )
+ {
+ halloc_free( terminfo_mappings );
+ }
+}
+
+const wchar_t *input_terminfo_get_sequence( const wchar_t *name )
+{
+ const char *res = 0;
+ int i;
+ static string_buffer_t *buff = 0;
+ int err = ENOENT;
+
+ CHECK( name, 0 );
+ input_init();
+
+ for( i=0; i<al_get_count( terminfo_mappings ); i++ )
+ {
+ terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
+
+ if( !wcscmp( name, m->name ) )
+ {
+ res = m->seq;
+ err = EILSEQ;
+ break;
+ }
+ }
+
+ if( !res )
+ {
+ errno = err;
+ return 0;
+ }
+
+ if( !buff )
+ {
+ buff = sb_halloc( global_context );
+ }
+
+ sb_clear( buff );
+ sb_printf( buff, L"%s", res );
+
+ return (wchar_t *)buff->buff;
+
+}
+
+const wchar_t *input_terminfo_get_name( const wchar_t *seq )
+{
+ int i;
+ static string_buffer_t *buff = 0;
+
+ CHECK( seq, 0 );
+ input_init();
+
+ if( !buff )
+ {
+ buff = sb_halloc( global_context );
+ }
+
+ for( i=0; i<al_get_count( terminfo_mappings ); i++ )
+ {
+ terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
+
+ if( !m->seq )
+ {
+ continue;
+ }
+
+ sb_clear( buff );
+ sb_printf( buff, L"%s", m->seq );
+
+ if( !wcscmp( seq, (wchar_t *)buff->buff ) )
+ {
+ return m->name;
+ }
+ }
+
+ return 0;
+
+}
+
+void input_terminfo_get_names( array_list_t *lst, int skip_null )
+{
+ int i;
+
+ CHECK( lst, );
+ input_init();
+
+ for( i=0; i<al_get_count( terminfo_mappings ); i++ )
+ {
+ terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
+
+ if( skip_null && !m->seq )
+ {
+ continue;
+ }
+ al_push( lst, m->name );
+ }
+}
+
+void input_function_get_names( array_list_t *lst )
+{
+ int i;
+
+ CHECK( lst, );
+
+ for( i=0; i<(sizeof(name_arr)/sizeof(wchar_t *)); i++ )
+ {
+ al_push( lst, name_arr[i] );
+ }
+}
+
+wchar_t input_function_get_code( const wchar_t *name )
+{
+
+ int i;
+ for( i = 0; i<(sizeof( code_arr )/sizeof(wchar_t)) ; i++ )
+ {
+ if( wcscmp( name, name_arr[i] ) == 0 )
+ {
+ return code_arr[i];
+ }
+ }
+ return -1;
+}
+