mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Initial blocking implementation
darcs-hash:20051211222101-ac50b-6e11220bd608187fbb32a0313b5b73dbdc8354fc.gz
This commit is contained in:
parent
2cac04850b
commit
1d69e70b7a
11 changed files with 390 additions and 68 deletions
14
Makefile.in
14
Makefile.in
|
@ -79,13 +79,13 @@ MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
|||
|
||||
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
|
||||
doc_src/break.txt doc_src/builtin.txt doc_src/case.txt \
|
||||
doc_src/cd.txt doc_src/command.txt doc_src/commandline.txt \
|
||||
doc_src/complete.txt doc_src/continue.txt doc_src/else.txt \
|
||||
doc_src/end.txt doc_src/eval.txt doc_src/exec.txt doc_src/exit.txt \
|
||||
doc_src/fg.txt doc_src/for.txt doc_src/function.txt \
|
||||
doc_src/functions.txt doc_src/if.txt doc_src/jobs.txt \
|
||||
doc_src/not.txt doc_src/or.txt doc_src/random.txt \
|
||||
doc_src/block.txt doc_src/break.txt doc_src/builtin.txt \
|
||||
doc_src/case.txt doc_src/cd.txt doc_src/command.txt \
|
||||
doc_src/commandline.txt doc_src/complete.txt doc_src/continue.txt \
|
||||
doc_src/else.txt doc_src/end.txt doc_src/eval.txt doc_src/exec.txt \
|
||||
doc_src/exit.txt doc_src/fg.txt doc_src/for.txt \
|
||||
doc_src/function.txt doc_src/functions.txt doc_src/if.txt \
|
||||
doc_src/jobs.txt doc_src/not.txt doc_src/or.txt doc_src/random.txt \
|
||||
doc_src/return.txt doc_src/read.txt doc_src/set.txt \
|
||||
doc_src/status.txt doc_src/switch.txt doc_src/ulimit.txt \
|
||||
doc_src/while.txt
|
||||
|
|
182
builtin.c
182
builtin.c
|
@ -244,6 +244,173 @@ static int builtin_bind( wchar_t **argv )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
The block builtin, used for temporarily blocking events
|
||||
*/
|
||||
static int builtin_block( wchar_t **argv )
|
||||
{
|
||||
enum
|
||||
{
|
||||
UNSET,
|
||||
GLOBAL,
|
||||
LOCAL,
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
int scope=UNSET;
|
||||
|
||||
int erase = 0;
|
||||
|
||||
int argc=builtin_count_args( argv );
|
||||
|
||||
int type = (1<<EVENT_ANY);
|
||||
|
||||
|
||||
woptind=0;
|
||||
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"local", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"global", no_argument, 0, 'g'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"elgh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
if(long_options[opt_index].flag != 0)
|
||||
break;
|
||||
sb_append2( sb_err,
|
||||
argv[0],
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
L" ",
|
||||
long_options[opt_index].name,
|
||||
L"\n",
|
||||
(void *)0);
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 0;
|
||||
|
||||
case 'g':
|
||||
scope = GLOBAL;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
scope = LOCAL;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
erase = 1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( erase )
|
||||
{
|
||||
if( scope != UNSET )
|
||||
{
|
||||
sb_printf( sb_err, L"%ls: Can not specify scope when removing block\n", argv[0] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( !global_event_block )
|
||||
{
|
||||
sb_printf( sb_err, L"%ls: No blocks defined\n", argv[0] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
event_block_t *eb = global_event_block;
|
||||
global_event_block = eb->next;
|
||||
free( eb );
|
||||
}
|
||||
else
|
||||
{
|
||||
block_t *block=current_block;
|
||||
|
||||
event_block_t *eb = malloc( sizeof( event_block_t ) );
|
||||
|
||||
if( !eb )
|
||||
die_mem();
|
||||
|
||||
eb->type = type;
|
||||
|
||||
switch( scope )
|
||||
{
|
||||
case LOCAL:
|
||||
{
|
||||
if( !block->outer )
|
||||
block=0;
|
||||
break;
|
||||
}
|
||||
case GLOBAL:
|
||||
{
|
||||
block=0;
|
||||
}
|
||||
case UNSET:
|
||||
{
|
||||
while( block && block->type != FUNCTION_CALL )
|
||||
block = block->outer;
|
||||
}
|
||||
}
|
||||
if( block )
|
||||
{
|
||||
eb->next = block->first_event_block;
|
||||
block->first_event_block = eb;
|
||||
}
|
||||
else
|
||||
{
|
||||
eb->next = global_event_block;
|
||||
global_event_block=eb;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
The builtin builtin, used for given builtins precedence over functions. Mostly handled by the parser. All this code does is some additional operational modes, such as printing a list of all builtins.
|
||||
|
@ -838,7 +1005,7 @@ static int builtin_function( wchar_t **argv )
|
|||
break;
|
||||
}
|
||||
|
||||
e = malloc( sizeof(event_t));
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
e->type = EVENT_SIGNAL;
|
||||
|
@ -862,7 +1029,7 @@ static int builtin_function( wchar_t **argv )
|
|||
break;
|
||||
}
|
||||
|
||||
e = malloc( sizeof(event_t));
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
e->type = EVENT_VARIABLE;
|
||||
|
@ -879,7 +1046,7 @@ static int builtin_function( wchar_t **argv )
|
|||
wchar_t *end;
|
||||
event_t *e;
|
||||
|
||||
e = malloc( sizeof(event_t));
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
|
||||
|
@ -2850,6 +3017,7 @@ void builtin_init()
|
|||
hash_init( &builtin, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
hash_put( &builtin, L"exit", (void*) &builtin_exit );
|
||||
hash_put( &builtin, L"block", (void*) &builtin_block );
|
||||
hash_put( &builtin, L"builtin", (void*) &builtin_builtin );
|
||||
hash_put( &builtin, L"cd", (void*) &builtin_cd );
|
||||
hash_put( &builtin, L"function", (void*) &builtin_function );
|
||||
|
@ -2899,6 +3067,7 @@ void builtin_init()
|
|||
|
||||
intern_static( L"exit" );
|
||||
intern_static( L"builtin" );
|
||||
intern_static( L"block" );
|
||||
intern_static( L"cd" );
|
||||
intern_static( L"function" );
|
||||
intern_static( L"functions" );
|
||||
|
@ -3026,11 +3195,13 @@ const wchar_t *builtin_get_desc( const wchar_t *b )
|
|||
|
||||
hash_init( desc, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
hash_put( desc, L"exit", L"Exit the shell" );
|
||||
hash_put( desc, L"block", L"Temporarily block delivery of events" );
|
||||
hash_put( desc, L"builtin", L"Run a builtin command" );
|
||||
hash_put( desc, L"complete", L"Edit command specific completions" );
|
||||
hash_put( desc, L"cd", L"Change working directory" );
|
||||
hash_put( desc, L"exit", L"Exit the shell" );
|
||||
hash_put( desc, L"function", L"Define a new function" );
|
||||
hash_put( desc, L"functions", L"List or remove functions" );
|
||||
hash_put( desc, L"complete", L"Edit command specific completions" );
|
||||
hash_put( desc, L"end", L"End a block of commands" );
|
||||
hash_put( desc, L"else", L"Evaluate block if condition is false" );
|
||||
hash_put( desc, L"eval", L"Evaluate parameters as a command" );
|
||||
|
@ -3047,7 +3218,6 @@ const wchar_t *builtin_get_desc( const wchar_t *b )
|
|||
hash_put( desc, L"commandline", L"Set the commandline" );
|
||||
hash_put( desc, L"switch", L"Conditionally execute a block of commands" );
|
||||
hash_put( desc, L"case", L"Conditionally execute a block of commands" );
|
||||
hash_put( desc, L"builtin", L"Run a builtin command" );
|
||||
hash_put( desc, L"command", L"Run a program" );
|
||||
hash_put( desc, L"if", L"Conditionally execute a command" );
|
||||
hash_put( desc, L"while", L"Perform a command multiple times" );
|
||||
|
|
|
@ -682,6 +682,7 @@ builtins or shellscript functions, and can only be used inside fish.
|
|||
- <a href="builtins.html#begin">begin</a>, execute a block of commands
|
||||
- <a href="builtins.html#bind">bind</a>, change keyboard bindings
|
||||
- <a href="builtins.html#break">break</a>, stop the execution of a loop
|
||||
- <a href="builtins.html#block">block</a>, Temporarily block delivery of events
|
||||
- <a href="builtins.html#builtin">builtin</a>, execute a builtin command
|
||||
- <a href="builtins.html#case">case</a>, conditionally execute a block of commands
|
||||
- <a href="builtins.html#cd">cd</a>, change the current directory
|
||||
|
@ -995,7 +996,10 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
|||
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
|
||||
- The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
||||
- Syntax highlighting should mark cd to non-existing directories as an error
|
||||
|
||||
- the code for printing the prompt should know about the most common escape sequences
|
||||
- block builtin
|
||||
- redo the jobs command
|
||||
- wait shellscript
|
||||
|
||||
\subsection todo-possible Possible features
|
||||
|
||||
|
|
24
env.c
24
env.c
|
@ -236,7 +236,6 @@ static void universal_callback( int type,
|
|||
|
||||
if( str )
|
||||
{
|
||||
array_list_t arg;
|
||||
event_t ev;
|
||||
|
||||
has_changed=1;
|
||||
|
@ -245,12 +244,12 @@ static void universal_callback( int type,
|
|||
ev.param1.variable=name;
|
||||
ev.function_name=0;
|
||||
|
||||
al_init( &arg );
|
||||
al_push( &arg, L"VARIABLE" );
|
||||
al_push( &arg, str );
|
||||
al_push( &arg, name );
|
||||
event_fire( &ev, &arg );
|
||||
al_destroy( &arg );
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, str );
|
||||
al_push( &ev.arguments, name );
|
||||
event_fire( &ev );
|
||||
al_destroy( &ev.arguments );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,7 +488,6 @@ void env_set( const wchar_t *key,
|
|||
int done=0;
|
||||
|
||||
event_t ev;
|
||||
array_list_t ev_list;
|
||||
int is_universal = 0;
|
||||
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
|
@ -669,14 +667,14 @@ void env_set( const wchar_t *key,
|
|||
ev.param1.variable = key;
|
||||
ev.function_name = 0;
|
||||
|
||||
al_init( &ev_list );
|
||||
al_push( &ev_list, L"VARIABLE" );
|
||||
al_push( &ev_list, key );
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, key );
|
||||
|
||||
// debug( 1, L"env_set: fire events on variable %ls", key );
|
||||
event_fire( &ev, &ev_list );
|
||||
event_fire( &ev );
|
||||
// debug( 1, L"env_set: return from event firing" );
|
||||
al_destroy( &ev_list );
|
||||
al_destroy( &ev.arguments );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
135
event.c
135
event.c
|
@ -67,6 +67,12 @@ static array_list_t *events;
|
|||
*/
|
||||
static array_list_t *killme;
|
||||
|
||||
/**
|
||||
List of events that have been sent but have not yet been delivered because they are blocked.
|
||||
*/
|
||||
static array_list_t *blocked;
|
||||
|
||||
|
||||
/**
|
||||
Tests if one event instance matches the definition of a event
|
||||
class. If the class defines a function name, that will also be a
|
||||
|
@ -120,7 +126,7 @@ static int event_match( event_t *class, event_t *instance )
|
|||
Create an identical copy of an event. Use deep copying, i.e. make
|
||||
duplicates of any strings used as well.
|
||||
*/
|
||||
static event_t *event_copy( event_t *event )
|
||||
static event_t *event_copy( event_t *event, int copy_arguments )
|
||||
{
|
||||
event_t *e = malloc( sizeof( event_t ) );
|
||||
if( !e )
|
||||
|
@ -133,12 +139,55 @@ static event_t *event_copy( event_t *event )
|
|||
if( e->type == EVENT_VARIABLE )
|
||||
e->param1.variable = wcsdup( e->param1.variable );
|
||||
|
||||
al_init( &e->arguments );
|
||||
if( copy_arguments )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( &event->arguments ); i++ )
|
||||
{
|
||||
al_push( &e->arguments, wcsdup( (wchar_t *)al_get( &event->arguments, i ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
static int event_is_blocked( event_t *e )
|
||||
{
|
||||
block_t *block;
|
||||
event_block_t *eb;
|
||||
|
||||
for( block = current_block; block; block = block->outer )
|
||||
{
|
||||
for( eb = block->first_event_block; eb; eb=eb->next )
|
||||
{
|
||||
if( eb->type & (1<<EVENT_ANY ) )
|
||||
return 1;
|
||||
if( eb->type & (1<<e->type) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for( eb = global_event_block; eb; eb=eb->next )
|
||||
{
|
||||
if( eb->type & (1<<EVENT_ANY ) )
|
||||
return 1;
|
||||
if( eb->type & (1<<e->type) )
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void event_add_handler( event_t *event )
|
||||
{
|
||||
event_t *e = event_copy( event );
|
||||
event_t *e;
|
||||
|
||||
e = event_copy( event, 0 );
|
||||
|
||||
if( !events )
|
||||
events = al_new();
|
||||
|
@ -268,7 +317,7 @@ static int event_is_killed( event_t *e )
|
|||
matches' path. This means that nothing is allocated/initialized
|
||||
unless that is needed.
|
||||
*/
|
||||
static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
static void event_fire_internal( event_t *event )
|
||||
{
|
||||
int i, j;
|
||||
string_buffer_t *b=0;
|
||||
|
@ -337,9 +386,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
|||
|
||||
sb_append( b, criterion->function_name );
|
||||
|
||||
for( j=0; j<al_get_count(arguments); j++ )
|
||||
for( j=0; j<al_get_count(&event->arguments); j++ )
|
||||
{
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( arguments, j), 0 );
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 0 );
|
||||
sb_append( b, L" " );
|
||||
sb_append( b, arg_esc );
|
||||
free( arg_esc );
|
||||
|
@ -385,15 +434,42 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
|||
/**
|
||||
Handle all pending signal events
|
||||
*/
|
||||
static void event_fire_signal_events()
|
||||
static void event_fire_delayed()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
if( blocked && is_event==1)
|
||||
{
|
||||
array_list_t *new_blocked = 0;
|
||||
|
||||
for( i=0; i<al_get_count( blocked ); i++ )
|
||||
{
|
||||
event_t *e = (event_t *)al_get( blocked, i );
|
||||
if( event_is_blocked( e ) )
|
||||
{
|
||||
if( !new_blocked )
|
||||
new_blocked = al_new();
|
||||
al_push( new_blocked, e );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( e );
|
||||
event_free( e );
|
||||
}
|
||||
}
|
||||
al_destroy( blocked );
|
||||
free( blocked );
|
||||
blocked = new_blocked;
|
||||
}
|
||||
|
||||
|
||||
|
||||
while( sig_list[active_list].count > 0 )
|
||||
{
|
||||
int i;
|
||||
signal_list_t *lst;
|
||||
event_t e;
|
||||
array_list_t a;
|
||||
al_init( &a );
|
||||
al_init( &e.arguments );
|
||||
|
||||
/*
|
||||
Switch signal lists
|
||||
|
@ -421,17 +497,26 @@ static void event_fire_signal_events()
|
|||
for( i=0; i<lst->count; i++ )
|
||||
{
|
||||
e.param1.signal = lst->signal[i];
|
||||
al_set( &a, 0, sig2wcs( e.param1.signal ) );
|
||||
event_fire_internal( &e, &a );
|
||||
al_set( &e.arguments, 0, sig2wcs( e.param1.signal ) );
|
||||
if( event_is_blocked( &e ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
al_push( blocked, event_copy(&e, 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( &e );
|
||||
}
|
||||
}
|
||||
|
||||
al_destroy( &a );
|
||||
al_destroy( &e.arguments );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void event_fire( event_t *event, array_list_t *arguments )
|
||||
void event_fire( event_t *event )
|
||||
{
|
||||
//int is_event_old = is_event;
|
||||
is_event++;
|
||||
|
@ -452,10 +537,23 @@ void event_fire( event_t *event, array_list_t *arguments )
|
|||
}
|
||||
else
|
||||
{
|
||||
event_fire_signal_events();
|
||||
|
||||
event_fire_delayed();
|
||||
|
||||
if( event )
|
||||
event_fire_internal( event, arguments );
|
||||
{
|
||||
if( event_is_blocked( event ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
|
||||
al_push( blocked, event_copy(event, 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( event );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is_event--;// = is_event_old;
|
||||
|
@ -487,9 +585,14 @@ void event_destroy()
|
|||
|
||||
void event_free( event_t *e )
|
||||
{
|
||||
/*
|
||||
When apropriate, we clear the argument vector
|
||||
*/
|
||||
al_foreach( &e->arguments, (void (*)(const void *))&free );
|
||||
al_destroy( &e->arguments );
|
||||
|
||||
free( (void *)e->function_name );
|
||||
if( e->type == EVENT_VARIABLE )
|
||||
free( (void *)e->param1.variable );
|
||||
free( e );
|
||||
}
|
||||
|
||||
|
|
17
event.h
17
event.h
|
@ -43,15 +43,17 @@ typedef struct
|
|||
union
|
||||
{
|
||||
/**
|
||||
Signal number for signal-type events.Use EVENT_ANY_SIGNAL to match any signal
|
||||
Signal number for signal-type events.Use EVENT_ANY_SIGNAL
|
||||
to match any signal
|
||||
*/
|
||||
int signal;
|
||||
/**
|
||||
Variable name for variable-type events.
|
||||
Variable name for variable-type events.
|
||||
*/
|
||||
const wchar_t *variable;
|
||||
/**
|
||||
Process id for process-type events. Use EVENT_ANY_PID to match any pid.
|
||||
Process id for process-type events. Use EVENT_ANY_PID to
|
||||
match any pid.
|
||||
*/
|
||||
pid_t pid;
|
||||
/**
|
||||
|
@ -65,6 +67,13 @@ typedef struct
|
|||
The name of the event handler function
|
||||
*/
|
||||
const wchar_t *function_name;
|
||||
|
||||
/**
|
||||
The argument list. Only used when sending a new event using
|
||||
event_fire. In all other situations, the value of this variable
|
||||
is ignored.
|
||||
*/
|
||||
array_list_t arguments;
|
||||
}
|
||||
event_t;
|
||||
|
||||
|
@ -98,7 +107,7 @@ int event_get( event_t *criterion, array_list_t *out );
|
|||
\param event the specific event whose handlers should fire
|
||||
\param arguments the argument string to send to the event handler function
|
||||
*/
|
||||
void event_fire( event_t *event, array_list_t *arguments );
|
||||
void event_fire( event_t *event );
|
||||
|
||||
/**
|
||||
Initialize the event-handling library
|
||||
|
|
2
input.c
2
input.c
|
@ -1270,7 +1270,7 @@ static int interrupt_handler()
|
|||
/*
|
||||
Fire any pending events
|
||||
*/
|
||||
event_fire( 0, 0 );
|
||||
event_fire( 0 );
|
||||
if( job_reap( 1 ) )
|
||||
repaint();
|
||||
if( reader_interupted() )
|
||||
|
|
15
parser.c
15
parser.c
|
@ -111,6 +111,8 @@ The fish parser. Contains functions for parsing code.
|
|||
/** Last error code */
|
||||
int error_code;
|
||||
|
||||
event_block_t *global_event_block=0;
|
||||
|
||||
/** Position of last error */
|
||||
|
||||
static int err_pos;
|
||||
|
@ -194,7 +196,7 @@ int block_count( block_t *b )
|
|||
|
||||
void parser_push_block( int type )
|
||||
{
|
||||
block_t *new = malloc( sizeof( block_t ));
|
||||
block_t *new = calloc( 1, sizeof( block_t ));
|
||||
|
||||
// debug( 2, L"Block push %ls %d\n", bl[type], block_count( current_block)+1 );
|
||||
new->outer = current_block;
|
||||
|
@ -230,6 +232,7 @@ void parser_push_block( int type )
|
|||
void parser_pop_block()
|
||||
{
|
||||
// debug( 2, L"Block pop %ls %d\n", bl[current_block->type], block_count(current_block)-1 );
|
||||
event_block_t *eb, *eb_next;
|
||||
|
||||
if( (current_block->type != FUNCTION_DEF ) &&
|
||||
(current_block->type != FAKE) &&
|
||||
|
@ -270,6 +273,12 @@ void parser_pop_block()
|
|||
|
||||
}
|
||||
|
||||
for( eb=current_block->first_event_block; eb; eb=eb_next )
|
||||
{
|
||||
eb_next = eb->next;
|
||||
free(eb);
|
||||
}
|
||||
|
||||
block_t *old = current_block;
|
||||
current_block = current_block->outer;
|
||||
free( old );
|
||||
|
@ -1996,7 +2005,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
|||
tok_init( current_tokenizer, cmd, 0 );
|
||||
error_code = 0;
|
||||
|
||||
event_fire( 0, 0 );
|
||||
event_fire( 0 );
|
||||
|
||||
while( tok_has_next( current_tokenizer ) &&
|
||||
!error_code &&
|
||||
|
@ -2004,7 +2013,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
|||
!exit_status() )
|
||||
{
|
||||
eval_job( current_tokenizer );
|
||||
event_fire( 0, 0 );
|
||||
event_fire( 0 );
|
||||
}
|
||||
|
||||
int prev_block_type = current_block->type;
|
||||
|
|
36
parser.h
36
parser.h
|
@ -11,6 +11,27 @@
|
|||
#include "util.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef struct event_block
|
||||
{
|
||||
/**
|
||||
The types of events to block. This is interpreted as a bitset
|
||||
whete the value is 1 for every bit corresponding to a blocked
|
||||
event type. For example, if EVENT_VARIABLE type events should
|
||||
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
|
||||
|
||||
Note that EVENT_ANY can be used to specify any event.
|
||||
*/
|
||||
int type;
|
||||
|
||||
/**
|
||||
The next event_block struct
|
||||
*/
|
||||
struct event_block *next;
|
||||
}
|
||||
event_block_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
block_t represents a block of commands.
|
||||
*/
|
||||
|
@ -21,12 +42,12 @@ typedef struct block
|
|||
int tok_pos; /**< The start index of the block */
|
||||
|
||||
/**
|
||||
Status for the current loop block. Can be anu of the values from the loop_status enum.
|
||||
Status for the current loop block. Can be any of the values from the loop_status enum.
|
||||
*/
|
||||
int loop_status;
|
||||
|
||||
/**
|
||||
The log that is currently evaluated in the specified block.
|
||||
The job that is currently evaluated in the specified block.
|
||||
*/
|
||||
job_t *job;
|
||||
|
||||
|
@ -68,8 +89,11 @@ typedef struct block
|
|||
array_list_t *function_events;
|
||||
} param4;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
|
||||
*/
|
||||
event_block_t *first_event_block;
|
||||
|
||||
/**
|
||||
Next outer block
|
||||
*/
|
||||
|
@ -159,6 +183,10 @@ enum parser_error
|
|||
/** The current innermost block */
|
||||
extern block_t *current_block;
|
||||
|
||||
/** Global event blocks */
|
||||
extern event_block_t *global_event_block;
|
||||
|
||||
|
||||
/** The current error code */
|
||||
extern int error_code;
|
||||
|
||||
|
|
25
proc.c
25
proc.c
|
@ -76,9 +76,10 @@ int proc_had_barrier;
|
|||
pid_t proc_last_bg_pid = 0;
|
||||
|
||||
/**
|
||||
List used to store arguments when firing events
|
||||
The event variable used to send all process event
|
||||
*/
|
||||
static array_list_t event_arg;
|
||||
static event_t event;
|
||||
|
||||
/**
|
||||
Stringbuffer used to create arguments when firing events
|
||||
*/
|
||||
|
@ -91,7 +92,7 @@ static string_buffer_t event_status;
|
|||
|
||||
void proc_init()
|
||||
{
|
||||
al_init( &event_arg );
|
||||
al_init( &event.arguments );
|
||||
sb_init( &event_pid );
|
||||
sb_init( &event_status );
|
||||
}
|
||||
|
@ -185,7 +186,7 @@ void job_free( job_t * j )
|
|||
|
||||
void proc_destroy()
|
||||
{
|
||||
al_destroy( &event_arg );
|
||||
al_destroy( &event.arguments );
|
||||
sb_destroy( &event_pid );
|
||||
sb_destroy( &event_status );
|
||||
while( first_job )
|
||||
|
@ -484,21 +485,21 @@ static void format_job_info( const job_t *j, const wchar_t *status )
|
|||
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||
{
|
||||
static event_t ev;
|
||||
|
||||
ev.type=type;
|
||||
ev.param1.pid = pid;
|
||||
event.type=type;
|
||||
event.param1.pid = pid;
|
||||
|
||||
al_push( &event_arg, msg );
|
||||
al_push( &event.arguments, msg );
|
||||
|
||||
sb_printf( &event_pid, L"%d", pid );
|
||||
al_push( &event_arg, event_pid.buff );
|
||||
al_push( &event.arguments, event_pid.buff );
|
||||
|
||||
sb_printf( &event_status, L"%d", status );
|
||||
al_push( &event_arg, event_status.buff );
|
||||
al_push( &event.arguments, event_status.buff );
|
||||
|
||||
event_fire( &ev, &event_arg );
|
||||
al_truncate( &event_arg, 0 );
|
||||
event_fire( &event );
|
||||
|
||||
al_truncate( &event.arguments, 0 );
|
||||
sb_clear( &event_pid );
|
||||
sb_clear( &event_status );
|
||||
}
|
||||
|
|
2
signal.c
2
signal.c
|
@ -305,7 +305,7 @@ static void default_handler(int signal, siginfo_t *info, void *context)
|
|||
e.param1.signal = signal;
|
||||
e.function_name=0;
|
||||
|
||||
event_fire( &e, 0 );
|
||||
event_fire( &e );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue