aboutsummaryrefslogtreecommitdiffhomepage
path: root/expand.cpp
diff options
context:
space:
mode:
authorGravatar Siteshwar Vashisht <siteshwar@gmail.com>2012-01-29 14:11:39 +0530
committerGravatar Siteshwar Vashisht <siteshwar@gmail.com>2012-01-29 14:11:39 +0530
commit1a5d866a916ab0f7e0630c4205f3fff9b6375a3e (patch)
tree241923557f288d9d1322c263a9a10aba08163390 /expand.cpp
parenta1d8ed83dd87ef963574ede8818e5fd7389f4c41 (diff)
parent062e423125bd29b3cae7ba045fca22bd2df3b1cd (diff)
buggy-auto-complete is not so buggy now. Merged branch 'buggy-auto-complete' into CPlusPlus
Diffstat (limited to 'expand.cpp')
-rw-r--r--expand.cpp431
1 files changed, 367 insertions, 64 deletions
diff --git a/expand.cpp b/expand.cpp
index ff62d540..7b347b5c 100644
--- a/expand.cpp
+++ b/expand.cpp
@@ -377,7 +377,7 @@ static int match_pid( const wchar_t *cmd,
static int find_process( const wchar_t *proc,
int flags,
- array_list_t *out )
+ std::vector<completion_t> &out )
{
DIR *dir;
wchar_t *pdir_name;
@@ -442,7 +442,9 @@ static int find_process( const wchar_t *proc,
{
result = (wchar_t *)malloc(sizeof(wchar_t)*16 );
swprintf( result, 16, L"%d", j->pgid );
- al_push( out, result );
+ completion_t data_to_push;
+ data_to_push.completion = result;
+ out.push_back( data_to_push);
found = 1;
}
}
@@ -472,7 +474,9 @@ static int find_process( const wchar_t *proc,
{
result = (wchar_t *)malloc(sizeof(wchar_t)*16 );
swprintf( result, 16, L"%d", j->pgid );
- al_push( out, result );
+ completion_t data_to_push;
+ data_to_push.completion = result;
+ out.push_back( data_to_push);
found = 1;
}
}
@@ -508,7 +512,9 @@ static int find_process( const wchar_t *proc,
{
result = (wchar_t *)malloc(sizeof(wchar_t)*16 );
swprintf( result, 16, L"%d", p->pid );
- al_push( out, result );
+ completion_t data_to_push;
+ data_to_push.completion = result;
+ out.push_back( data_to_push );
found = 1;
}
}
@@ -623,8 +629,11 @@ static int find_process( const wchar_t *proc,
else
{
wchar_t *res = wcsdup(name);
- if( res )
- al_push( out, res );
+ if( res ) {
+ completion_t data_to_push;
+ data_to_push.completion = res;
+ out.push_back( data_to_push );
+ }
}
}
}
@@ -646,15 +655,17 @@ static int find_process( const wchar_t *proc,
*/
static int expand_pid( wchar_t *in,
int flags,
- array_list_t *out )
+ std::vector<completion_t> &out )
{
CHECK( in, 0 );
- CHECK( out, 0 );
+// CHECK( out, 0 );
if( *in != PROCESS_EXPAND )
{
- al_push( out, in );
+ completion_t data_to_push;
+ data_to_push.completion = in;
+ out.push_back( data_to_push );
return 1;
}
@@ -682,7 +693,11 @@ static int expand_pid( wchar_t *in,
wchar_t *str= (wchar_t *)malloc( sizeof(wchar_t)*32);
free(in);
swprintf( str, 32, L"%d", getpid() );
- al_push( out, str );
+
+ completion_t data_to_push;
+ data_to_push.completion = str;
+
+ out.push_back( data_to_push );
return 1;
}
@@ -695,18 +710,21 @@ static int expand_pid( wchar_t *in,
str = (wchar_t *)malloc( sizeof(wchar_t)*32);
free(in);
swprintf( str, 32, L"%d", proc_last_bg_pid );
- al_push( out, str );
+ completion_t data_to_push;
+ data_to_push.completion = str;
+
+ out.push_back( data_to_push);
}
return 1;
}
}
- int prev = al_get_count( out );
+ int prev = out.size();
if( !find_process( in+1, flags, out ) )
return 0;
- if( prev == al_get_count( out ) )
+ if( prev == out.size() )
{
if( flags & ACCEPT_INCOMPLETE )
free( in );
@@ -723,13 +741,13 @@ static int expand_pid( wchar_t *in,
return 1;
}
-
-static int expand_pid2( const wcstring &in, int flags, std::vector<wcstring> &outputs )
+/*
+static int expand_pid2( const wcstring &in, int flags, std::vector<completion_t> &outputs )
{
wcstring_adapter adapter(in, outputs);
return expand_pid(adapter.str, flags, &adapter.lst);
}
-
+*/
void expand_variable_error( parser_t &parser, const wchar_t *token, int token_pos, int error_pos )
{
@@ -1187,16 +1205,282 @@ static int expand_variables( parser_t &parser, wchar_t *in, array_list_t *out, i
return is_ok;
}
-static int expand_variables2( parser_t &parser, const wcstring &in, std::vector<wcstring> &outputs, int last_idx )
+static int expand_variables2( parser_t &parser, wchar_t * in, std::vector<completion_t> &out, int last_idx )
{
- wcstring_adapter adapter(in, outputs);
- return expand_variables(parser, adapter.str, &adapter.lst, last_idx);
+ wchar_t c;
+ wchar_t prev_char=0;
+ int i, j;
+ int is_ok= 1;
+ int empty=0;
+
+ static string_buffer_t *var_tmp = 0;
+ static array_list_t *var_idx_list = 0;
+
+ CHECK( in, 0 );
+// CHECK( out, 0 );
+
+ if( !var_tmp )
+ {
+ var_tmp = sb_halloc( global_context );
+ if( !var_tmp )
+ DIE_MEM();
+ }
+ else
+ {
+ sb_clear(var_tmp );
+ }
+
+ if( !var_idx_list )
+ {
+ var_idx_list = al_halloc( global_context );
+ if( !var_idx_list )
+ DIE_MEM();
+ }
+ else
+ {
+ al_truncate( var_idx_list, 0 );
+ }
+
+ for( i=last_idx; (i>=0) && is_ok && !empty; i-- )
+ {
+ c = in[i];
+ if( ( c == VARIABLE_EXPAND ) || (c == VARIABLE_EXPAND_SINGLE ) )
+ {
+ int start_pos = i+1;
+ int stop_pos;
+ int var_len, new_len;
+ const wchar_t * var_val;
+ wchar_t * new_in;
+ int is_single = (c==VARIABLE_EXPAND_SINGLE);
+ int var_name_stop_pos;
+
+ stop_pos = start_pos;
+
+ while( 1 )
+ {
+ if( !(in[stop_pos ]) )
+ break;
+ if( !( iswalnum( in[stop_pos] ) ||
+ (wcschr(L"_", in[stop_pos])!= 0) ) )
+ break;
+
+ stop_pos++;
+ }
+ var_name_stop_pos = stop_pos;
+
+/* printf( "Stop for '%c'\n", in[stop_pos]);*/
+
+ var_len = stop_pos - start_pos;
+
+ if( var_len == 0 )
+ {
+ expand_variable_error( parser_t::principal_parser(), in, stop_pos-1, -1 );
+
+ is_ok = 0;
+ break;
+ }
+
+ sb_append_substring( var_tmp, &in[start_pos], var_len );
+ var_val = expand_var( (wchar_t *)var_tmp->buff );
+
+ if( var_val )
+ {
+ int all_vars=1;
+ array_list_t var_item_list;
+ al_init( &var_item_list );
+
+ if( in[stop_pos] == L'[' )
+ {
+ wchar_t *slice_end;
+ all_vars=0;
+
+ if( parse_slice( &in[stop_pos], &slice_end, var_idx_list ) )
+ {
+ parser_t::principal_parser().error( SYNTAX_ERROR,
+ -1,
+ L"Invalid index value" );
+ is_ok = 0;
+ }
+ stop_pos = (slice_end-in);
+ }
+
+ if( is_ok )
+ {
+ tokenize_variable_array( var_val, &var_item_list );
+ if( !all_vars )
+ {
+ int j;
+ for( j=0; j<al_get_count( var_idx_list ); j++)
+ {
+ long tmp = al_get_long( var_idx_list, j );
+ if( tmp < 0 )
+ {
+ tmp = al_get_count( &var_item_list)+tmp+1;
+ }
+
+ /*
+ Check that we are within array
+ bounds. If not, truncate the list to
+ exit.
+ */
+ if( tmp < 1 || tmp > al_get_count( &var_item_list ) )
+ {
+ parser_t::principal_parser().error( SYNTAX_ERROR,
+ -1,
+ ARRAY_BOUNDS_ERR );
+ is_ok=0;
+ al_truncate( var_idx_list, j );
+ break;
+ }
+ else
+ {
+ /* Replace each index in var_idx_list inplace with the string value at the specified index */
+ al_set( var_idx_list, j, wcsdup((const wchar_t *)al_get( &var_item_list, tmp-1 ) ) );
+ }
+ }
+ /* Free strings in list var_item_list and truncate it */
+ al_foreach( &var_item_list, &free );
+ al_truncate( &var_item_list, 0 );
+ /* Add items from list idx back to list l */
+ al_push_all( &var_item_list, var_idx_list );
+ }
+ }
+
+ if( is_ok )
+ {
+
+ if( is_single )
+ {
+ string_buffer_t res;
+ in[i]=0;
+
+ sb_init( &res );
+ sb_append( &res, in );
+ sb_append_char( &res, INTERNAL_SEPARATOR );
+
+ for( j=0; j<al_get_count( &var_item_list); j++ )
+ {
+ wchar_t *next = (wchar_t *)al_get( &var_item_list, j );
+
+ if( is_ok )
+ {
+ if( j != 0 )
+ sb_append( &res, L" " );
+ sb_append( &res, next );
+ }
+ free( next );
+ }
+ sb_append( &res, &in[stop_pos] );
+ is_ok &= expand_variables2( parser_t::principal_parser(), (wchar_t *)res.buff, out, i );
+ }
+ else
+ {
+ for( j=0; j<al_get_count( &var_item_list); j++ )
+ {
+ wchar_t *next = (wchar_t *)al_get( &var_item_list, j );
+ if( is_ok && (i == 0) && (!in[stop_pos]) )
+ {
+ completion_t data_to_push;
+ data_to_push.completion = next;
+ out.push_back( data_to_push );
+ }
+ else
+ {
+
+ if( is_ok )
+ {
+ new_len = wcslen(in) - (stop_pos-start_pos+1);
+ new_len += wcslen( next) +2;
+
+ if( !(new_in = (wchar_t *)malloc( sizeof(wchar_t)*new_len )))
+ {
+ DIE_MEM();
+ }
+ else
+ {
+
+ wcslcpy( new_in, in, start_pos );
+
+ if(start_pos>1 && new_in[start_pos-2]!=VARIABLE_EXPAND)
+ {
+ new_in[start_pos-1]=INTERNAL_SEPARATOR;
+ new_in[start_pos]=L'\0';
+ }
+ else
+ new_in[start_pos-1]=L'\0';
+
+ wcscat( new_in, next );
+ wcscat( new_in, &in[stop_pos] );
+
+ is_ok &= expand_variables2( parser_t::principal_parser(), new_in, out, i );
+ }
+ }
+ free( next );
+ }
+
+ }
+ }
+ }
+
+ free(in);
+ al_destroy( &var_item_list );
+ return is_ok;
+ }
+ else
+ {
+ /*
+ Expand a non-existing variable
+ */
+ if( c == VARIABLE_EXPAND )
+ {
+ /*
+ Regular expansion, i.e. expand this argument to nothing
+ */
+ empty = 1;
+ }
+ else
+ {
+ /*
+ Expansion to single argument.
+ */
+ string_buffer_t res;
+ sb_init( &res );
+
+ in[i]=0;
+
+ sb_append( &res, in );
+ sb_append( &res, &in[stop_pos] );
+
+ is_ok &= expand_variables2( parser_t::principal_parser(), (wchar_t *)res.buff, out, i );
+ free(in);
+ return is_ok;
+ }
+ }
+
+
+ }
+
+ prev_char = c;
+ }
+
+ if( !empty )
+ {
+ completion_t data_to_push;
+ data_to_push.completion = in;
+ out.push_back( data_to_push );
+ }
+ else
+ {
+ free( in );
+ }
+
+ return is_ok;
}
/**
Perform bracket expansion
*/
-static int expand_brackets( parser_t &parser, wchar_t *in, int flags, array_list_t *out )
+static int expand_brackets(parser_t &parser, wchar_t *in, int flags, std::vector<completion_t> &out )
{
wchar_t *pos;
int syntax_error=0;
@@ -1209,7 +1493,7 @@ static int expand_brackets( parser_t &parser, wchar_t *in, int flags, array_list
int len1, len2, tot_len;
CHECK( in, 0 );
- CHECK( out, 0 );
+// CHECK( out, 0 );
for( pos=in;
(*pos) && !syntax_error;
@@ -1284,7 +1568,9 @@ static int expand_brackets( parser_t &parser, wchar_t *in, int flags, array_list
if( bracket_begin == 0 )
{
- al_push( out, in );
+ completion_t data_to_push;
+ data_to_push.completion = in;
+ out.push_back( data_to_push );
return 1;
}
@@ -1328,12 +1614,13 @@ static int expand_brackets( parser_t &parser, wchar_t *in, int flags, array_list
return 1;
}
-static int expand_brackets2( parser_t &parser, const wcstring &in, int flags, std::vector<wcstring> outputs )
+/*
+static int expand_brackets2( parser_t &parser, const wcstring &in, int flags, std::vector<wcstring> &outputs )
{
wcstring_adapter adapter(in, outputs);
return expand_brackets(parser, adapter.str, flags, &adapter.lst);
}
-
+*/
/**
Perform cmdsubst expansion
*/
@@ -1487,7 +1774,7 @@ static int expand_cmdsubst( parser_t &parser, wchar_t *in, array_list_t *out )
/**
Perform cmdsubst expansion
*/
-static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vector<wcstring> &outList )
+static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vector<completion_t> &outList )
{
wchar_t *paran_begin=0, *paran_end=0;
int len1;
@@ -1499,7 +1786,9 @@ static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vecto
const wchar_t * const in = input.c_str();
- switch( parse_util_locate_cmdsubst(in,
+ completion_t data_to_push;
+ int parse_ret;
+ switch( parse_ret = parse_util_locate_cmdsubst(in,
&paran_begin,
&paran_end,
0 ) )
@@ -1510,7 +1799,8 @@ static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vecto
L"Mismatched parans" );
return 0;
case 0:
- outList.push_back(input);
+ data_to_push.completion = input;
+ outList.push_back(data_to_push);
return 1;
case 1:
@@ -1574,7 +1864,7 @@ static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vecto
substitutions. The result of this recursive call using the tail
of the string is inserted into the tail_expand array list
*/
- std::vector<wcstring> tail_expand;
+ std::vector<completion_t> tail_expand;
expand_cmdsubst2( parser, tail_begin, tail_expand );
/*
@@ -1591,7 +1881,7 @@ static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vecto
wcstring whole_item;
- wcstring tail_item = tail_expand.at(j);
+ wcstring tail_item = tail_expand.at(j).completion;
//sb_append_substring( &whole_item, in, len1 );
whole_item.append(in, len1);
@@ -1609,7 +1899,9 @@ static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vecto
whole_item.append(tail_item);
//al_push( out, whole_item.buff );
- outList.push_back(whole_item);
+ completion_t data_to_push;
+ data_to_push.completion = whole_item;
+ outList.push_back(data_to_push);
}
}
@@ -1766,11 +2058,11 @@ static void remove_internal_separator2( wcstring &s, int conv )
}
-int expand_string2( const wcstring &input, std::vector<wcstring> &output, int flags )
+int expand_string2( const wcstring &input, std::vector<completion_t> &output, int flags )
{
parser_t &parser = parser_t::principal_parser();
- std::vector<wcstring> list1, list2;
- std::vector<wcstring> *in, *out;
+ std::vector<completion_t> list1, list2;
+ std::vector<completion_t> *in, *out;
size_t i;
int cmdsubst_ok = 1;
@@ -1778,7 +2070,9 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
if( (!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean( input.c_str() ) )
{
- output.push_back(input);
+ completion_t data_to_push;
+ data_to_push.completion = input;
+ output.push_back(data_to_push);
return EXPAND_OK;
}
@@ -1794,7 +2088,9 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
parser.error( CMDSUBST_ERROR, -1, L"Command substitutions not allowed" );
return EXPAND_ERROR;
}
- list1.push_back(input);
+ completion_t data_to_push;
+ data_to_push.completion = input;
+ list1.push_back(data_to_push);
}
else
{
@@ -1818,7 +2114,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
commandline.
*/
int unescape_flags = UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE;
- wcstring next = expand_unescape_string( in->at(i), unescape_flags );
+ wcstring next = expand_unescape_string( in->at(i).completion, unescape_flags );
if( EXPAND_SKIP_VARIABLES & flags )
{
@@ -1827,11 +2123,13 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
next[i] = L'$';
}
}
- out->push_back(next);
+ completion_t data_to_push;
+ data_to_push.completion = next;
+ out->push_back(data_to_push);
}
else
{
- if(!expand_variables2( parser, next, *out, next.size() - 1 ))
+ if(!expand_variables2( parser, wcsdup(next.c_str()), *out, next.size() - 1 ))
{
return EXPAND_ERROR;
}
@@ -1845,9 +2143,9 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
for( i=0; i < in->size(); i++ )
{
- wcstring next = in->at(i);
+ wcstring next = in->at(i).completion;
- if( !expand_brackets2( parser, next, flags, *out ))
+ if( !expand_brackets( parser, wcsdup(next.c_str()), flags, *out ))
{
return EXPAND_ERROR;
}
@@ -1859,7 +2157,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
for( i=0; i < in->size(); i++ )
{
- wcstring next = in->at(i);
+ wcstring next = in->at(i).completion;
expand_tilde_internal(next);
@@ -1873,17 +2171,19 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
interested in other completions, so we
short-circut and return
*/
- expand_pid2( next, flags, output );
+ expand_pid( wcsdup(next.c_str()), flags, output );
return EXPAND_OK;
}
else
{
- out->push_back(next);
+ completion_t data_to_push;
+ data_to_push.completion = next;
+ out->push_back(data_to_push);
}
}
else
{
- if( !expand_pid2( next, flags, *out ) )
+ if( !expand_pid( wcsdup(next.c_str()), flags, *out ) )
{
return EXPAND_ERROR;
}
@@ -1897,7 +2197,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
for( i=0; i < in->size(); i++ )
{
- wcstring next_str = in->at(i);
+ wcstring next_str = in->at(i).completion;
int wc_res;
remove_internal_separator2( next_str, EXPAND_SKIP_WILDCARDS & flags );
@@ -1907,7 +2207,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
wildcard_has( next, 1 ) )
{
const wchar_t *start, *rest;
- std::vector<wcstring> *list = out;
+ std::vector<completion_t> *list = out;
if( next[0] == '/' )
{
@@ -1925,7 +2225,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
list = &output;
}
- wc_res = wildcard_expand_string(rest, start, flags, *list);
+ wc_res = wildcard_expand_string(rest, start, flags, *list);
if( !(flags & ACCEPT_INCOMPLETE) )
{
@@ -1946,12 +2246,11 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
{
size_t j;
res = EXPAND_WILDCARD_MATCH;
- sort_strings( *out );
+ sort_completions( *out );
for( j=0; j< out->size(); j++ )
{
- wcstring next = out->at(j);
- output.push_back(next);
+ output.push_back( out->at(j) );
}
out->clear();
break;
@@ -1973,7 +2272,9 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
}
else
{
- output.push_back(next);
+ completion_t data_to_push;
+ data_to_push.completion = next;
+ output.push_back(data_to_push);
}
}
@@ -1986,6 +2287,7 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &output, int fl
/**
The real expansion function. expand_one is just a wrapper around this one.
*/
+/*
int expand_string( void *context,
wchar_t *str,
array_list_t *end_out,
@@ -2048,13 +2350,13 @@ int expand_string( void *context,
for( i=0; i<al_get_count( in ); i++ )
{
wchar_t *next;
-
+*/
/*
We accept incomplete strings here, since complete uses
expand_string to expand incomplete strings from the
commandline.
*/
- int unescape_flags = UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE;
+/* int unescape_flags = UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE;
next = expand_unescape( parser, (wchar_t *)al_get( in, i ), unescape_flags );
@@ -2132,13 +2434,13 @@ int expand_string( void *context,
if( flags & ACCEPT_INCOMPLETE )
{
if( *next == PROCESS_EXPAND )
- {
+ {*/
/*
If process expansion matches, we are not
interested in other completions, so we
short-circut and return
*/
- expand_pid( next, flags, end_out );
+/* expand_pid( next, flags, end_out );
al_destroy( in );
al_destroy( out );
return EXPAND_OK;
@@ -2278,11 +2580,11 @@ int expand_string( void *context,
return res;
}
-
+*/
wchar_t *expand_one( void *context, wchar_t *string, int flags )
{
- array_list_t l;
+ std::vector<completion_t> l;
int res;
wchar_t *one;
@@ -2294,29 +2596,30 @@ wchar_t *expand_one( void *context, wchar_t *string, int flags )
return string;
}
- al_init( &l );
- res = expand_string( 0, string, &l, flags );
+// al_init( &l );
+ res = expand_string2( string, l, flags );
if( !res )
{
one = 0;
}
else
{
- if( al_get_count( &l ) != 1 )
+ if( l.size() != 1 )
{
one=0;
}
else
{
- one = (wchar_t *)al_get( &l, 0 );
- al_set( &l, 0, 0 );
+ one = wcsdup( l.at(0).completion.c_str() );
+// al_set( &l, 0, 0 );
}
}
- al_foreach( &l, &free );
- al_destroy( &l );
+// al_foreach( &l, &free );
+// al_destroy( &l );
halloc_register( context, one );
return one;
}
+