Skip to content

Commit

Permalink
added feature: searching if completion string exists
Browse files Browse the repository at this point in the history
Signed-off-by: maciej <[email protected]>
  • Loading branch information
m-kaminski committed May 31, 2015
1 parent 9bc665a commit 21a48d9
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 61 deletions.
82 changes: 58 additions & 24 deletions auto_complete.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,6 @@ static int history[MAX_NUM_HISTORY][COMMANDLEN_MAX];
static size_t total_history_entries = 0;
static size_t last_history_entry = -1;


/* main api function */
void init_completion(char*compl)
{
int i;
for (i = 0 ; compl[i]; ++i)
completions[current_num_completions][i]=compl[i];
completions[current_num_completions][i] = 0;
current_num_completions++;
}

/* helper for qsort*/
int compl_lesscomp(const void *s1, const void *s2)
{
return memcmp(s1, s2, COMMANDLEN_MAX);
}

/* main api function */
void init_completions()
{
qsort(completions, current_num_completions, sizeof(completions[0]),
compl_lesscomp);
}

/**
* global variable used for passing state to comparison functions
* called by lfind etc.
Expand All @@ -81,6 +57,15 @@ int compl_neqcompar(const void *key, const void *s2)
return !memcmp(key, s2, memsize*4);
}

/**
* find first and last completion string iterator, that matches first <u>size</u>
* bytes from string given in parameter <u>begin</u>
*
* @param[in] begin string which we search for
* @param[in] size amount of characters to match
* @param[out] it_begin first match
* @param[out] it_end last match
*/
void compute_completion_ranges(int* begin, int size, int **it_begin, int **it_end)
{
memsize=size;
Expand Down Expand Up @@ -466,6 +451,55 @@ char *getline_complete(char *prompt)
return line_t;
}

/* main api function */
void init_completion(char *compl)
{
int i;
for (i = 0 ; compl[i]; ++i) {
if (i == TOKENLEN_MAX-1) {
break;
}
completions[current_num_completions][i]=compl[i];
}
completions[current_num_completions][i] = 0;
current_num_completions++;
}

/* helper for qsort*/
int compl_lesscomp(const void *s1, const void *s2)
{
return memcmp(s1, s2, COMMANDLEN_MAX);
}

/* main api function */
void init_completions()
{
qsort(completions, current_num_completions, sizeof(completions[0]),
compl_lesscomp);
}

/* main api function */
int completion_exists(char *compl)
{
int i;
int *it_begin;
int tmp[TOKENLEN_MAX];
for (i = 0 ; compl[i]; ++i) {
if (i == TOKENLEN_MAX-1) {
break;
}
tmp[i]=compl[i];
}

tmp[i] = 0;
memsize = i; /* compare amount of characters equivalent to lenth of compl
* plus a NULL-terminator */
it_begin = (int*)(lfind(tmp, completions,
&current_num_completions, sizeof(completions[0]),
compl_eqcompar));
return it_begin != NULL;
}

/* main api function */
void print_history()
{
Expand Down
85 changes: 48 additions & 37 deletions auto_complete.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,6 @@
#ifndef __AUTO_COMPLETE_
#define __AUTO_COMPLETE_

/*
* If you feel that you need more history entries, more possible completions
* or longer commands, feel free to adjust following macros.
*
* Note that library holds static arrays of size:
* COMMANDLEN_MAX*MAX_NUM_COMPLETIONS*sizeof(int)
* and COMMANDLEN_MAX*MAX_NUM_HISTORY*sizeof(int)
*
* and thus if you'll increase these above common sense, memory footprint of
* your program will grow substantially.
*/

/**! maximum length of command */
#define COMMANDLEN_MAX 4096

/**! maximum number of possible completions */
#define MAX_NUM_COMPLETIONS 2048

/**! number of history entries */
#define MAX_NUM_HISTORY 200


/**
* Add a string onto list of possible completions
*
* @param[in] compl a string to which text inserted may be expanded (in aclib lingo: availabe completion)
*/
void init_completion(char*compl);

/**
* Helper routine - must be called after init_completion and before getline_complete.
* - it sorts completions within internal tables of aclib.
* if no new completions are added, there is no need to call this routine between calls to
* getline_complete
*/
void init_completions();

/**
* Reads command from standard input.
* Returns null terminated string (not including newline character).
Expand Down Expand Up @@ -78,9 +41,57 @@ void init_completions();
*/
char *getline_complete(char *prompt);

/**
* Add a string onto list of possible completions
*
* Don't add same string to table more than once. This routine won't detect it.
* completion search functions will probably work all right, but you will use more memory than
* you actually need. To check if completion exists (i.e. in application that periodically adds
* more completions to its table) use completion_exists routine.
*
* @param[in] compl a string to which text inserted may be expanded (in aclib lingo: availabe completion)
*/
void init_completion(char *compl);

/**
* check if string given is within completion table
*
* @param[in] compl a string to be checked.
*/
int completion_exists(char *compl);

/**
* Helper routine - must be called after init_completion and before getline_complete.
* - it sorts completions within internal tables of aclib.
* if no new completions are added, there is no need to call this routine between calls to
* getline_complete
*/
void init_completions();

/**
* Prints history to stdout.
*/
void print_history();

/*
* If you feel that you need more history entries, more possible completions
* or longer commands, feel free to adjust following macros.
*
* Note that library holds static arrays of size:
* COMMANDLEN_MAX*MAX_NUM_COMPLETIONS*sizeof(int)
* and COMMANDLEN_MAX*MAX_NUM_HISTORY*sizeof(int)
*
* and thus if you'll increase these above common sense, memory footprint of
* your program will grow substantially.
*/

/**! maximum length of command */
#define COMMANDLEN_MAX 4096

/**! maximum number of possible completions */
#define MAX_NUM_COMPLETIONS 2048

/**! number of history entries */
#define MAX_NUM_HISTORY 200

#endif
4 changes: 4 additions & 0 deletions example.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "auto_complete.h"

#define MAX_COMMAND_LENGTH 20
Expand Down Expand Up @@ -64,13 +65,16 @@ int main()
void setup()
{
/* add internal commands as possible completions */
assert(!completion_exists("help"));
init_completion("help");
init_completion("history");
init_completion("exit");
assert(completion_exists("history"));

/* add some random bullshit as possible completions - in real life program
* these would be possibly legal parameters to said commands.
*/
assert(!completion_exists("alpha.omega"));
init_completion("alpha.omega");
init_completion("alpha.zeta");
init_completion("beta");
Expand Down

0 comments on commit 21a48d9

Please sign in to comment.