2005-09-20 23:26:39 +10:00
/*
Copyright ( C ) 2005 Axel Liljencrantz
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
/** \file main.c
The main loop of < tt > fish < / tt > .
*/
# include "config.h"
# include <stdlib.h>
# include <stdio.h>
# include <wchar.h>
# include <string.h>
# include <unistd.h>
# include <errno.h>
# include <unistd.h>
# include <termios.h>
# include <sys/types.h>
# include <fcntl.h>
# ifdef HAVE_GETOPT_H
# include <getopt.h>
# endif
# include <locale.h>
# include <signal.h>
# include "util.h"
# include "common.h"
# include "reader.h"
# include "builtin.h"
# include "function.h"
# include "complete.h"
# include "wutil.h"
# include "env.h"
# include "sanity.h"
# include "proc.h"
# include "parser.h"
# include "expand.h"
# include "intern.h"
/**
Parse init files
*/
static int read_init ( )
{
char cwd [ 4096 ] ;
wchar_t * wcwd ;
if ( ! getcwd ( cwd , 4096 ) )
{
wperror ( L " getcwd " ) ;
return 0 ;
}
env_set ( L " __fish_help_dir " , DOCDIR , 0 ) ;
2005-09-26 22:33:06 +10:00
eval ( L " builtin cd " SYSCONFDIR L " 2>/dev/null; . fish 2>/dev/null " , 0 , TOP ) ;
2005-09-20 23:26:39 +10:00
eval ( L " builtin cd 2>/dev/null;. .fish 2>/dev/null " , 0 , TOP ) ;
if ( chdir ( cwd ) = = - 1 )
{
// fwprintf( stderr, L"Invalid directory: %s\n", cwd );
// wperror( L"chdir" );
// return 0;
}
wcwd = str2wcs ( cwd ) ;
if ( wcwd )
{
env_set ( L " PWD " , wcwd , ENV_EXPORT ) ;
free ( wcwd ) ;
}
return 1 ;
}
/**
Calls a bunch of init functions , parses the init files and then
parses commands from stdin or files , depending on arguments
*/
int main ( int argc , char * * argv )
{
int res = 1 ;
int force_interactive = 0 ;
int my_optind ;
char * cmd = 0 ;
fish_setlocale ( LC_ALL , L " " ) ;
is_interactive_session = 1 ;
program_name = L " fish " ;
while ( 1 )
{
# ifdef __GLIBC__
static struct option
long_options [ ] =
{
{
" command " , required_argument , 0 , ' c '
}
,
{
" interactive " , no_argument , 0 , ' i '
}
,
{
" profile " , required_argument , 0 , ' p '
}
,
{
" help " , no_argument , 0 , ' h '
}
,
{
" version " , no_argument , 0 , ' v '
}
,
{
0 , 0 , 0 , 0
}
}
;
int opt_index = 0 ;
int opt = getopt_long ( argc ,
argv ,
" hivc:p: " ,
long_options ,
& opt_index ) ;
# else
int opt = getopt ( argc ,
argv ,
" hivc:p: " ) ;
# endif
if ( opt = = - 1 )
break ;
switch ( opt )
{
case 0 :
break ;
case ' c ' :
cmd = optarg ;
is_interactive_session = 0 ;
break ;
case ' h ' :
cmd = " help " ;
//interactive=0;
break ;
case ' i ' :
force_interactive = 1 ;
break ;
case ' p ' :
profile = optarg ;
break ;
case ' v ' :
fwprintf ( stderr ,
L " %s, version %s \n " ,
PACKAGE_NAME ,
PACKAGE_VERSION ) ;
exit ( 0 ) ;
case ' ? ' :
return 1 ;
}
}
my_optind = optind ;
is_login | = strcmp ( argv [ 0 ] , " -fish " ) = = 0 ;
// fwprintf( stderr, L"%s\n", argv[0] );
is_interactive_session & = ( cmd = = 0 ) ;
is_interactive_session & = ( my_optind = = argc ) ;
is_interactive_session & = isatty ( STDIN_FILENO ) ;
// fwprintf( stderr, L"%d %d %d\n", cmd==0, my_optind == argc, isatty(STDIN_FILENO) );
if ( force_interactive )
is_interactive_session = 1 ;
parser_init ( ) ;
builtin_init ( ) ;
function_init ( ) ;
env_init ( ) ;
complete_init ( ) ;
reader_init ( ) ;
reader_push_current_filename ( L " (internal) " ) ;
if ( read_init ( ) )
{
if ( cmd ! = 0 )
{
wchar_t * cmd_wcs = str2wcs ( cmd ) ;
res = eval ( cmd_wcs , 0 , TOP ) ;
free ( cmd_wcs ) ;
reader_exit ( 0 ) ;
}
else
{
if ( my_optind = = argc )
{
reader_push_current_filename ( L " (stdin) " ) ;
res = reader_read ( ) ;
reader_pop_current_filename ( ) ;
}
else
{
char * * ptr ;
char * file = * ( argv + 1 ) ;
int i ;
string_buffer_t sb ;
if ( close ( 0 ) )
{
wperror ( L " close " ) ;
return 1 ;
}
if ( open ( file , O_RDONLY ) = = - 1 )
{
wperror ( L " open " ) ;
return 1 ;
}
sb_init ( & sb ) ;
if ( * ( argv + 2 ) )
{
for ( i = 1 , ptr = argv + 2 ; * ptr ; i + + , ptr + + )
{
if ( i ! = 1 )
sb_append ( & sb , ARRAY_SEP_STR ) ;
wchar_t * val = str2wcs ( * ptr ) ;
sb_append ( & sb , val ) ;
free ( val ) ;
}
env_set ( L " argv " , ( wchar_t * ) sb . buff , 0 ) ;
sb_destroy ( & sb ) ;
}
reader_push_current_filename ( str2wcs ( file ) ) ;
res = reader_read ( ) ;
if ( res )
{
debug ( 1 ,
L " Error while reading file %ls \n " ,
reader_current_filename ( ) ) ;
}
free ( reader_pop_current_filename ( ) ) ;
}
}
}
if ( function_exists ( L " fish_on_exit " ) )
{
eval ( L " fish_on_exit " , 0 , TOP ) ;
}
job_do_notification ( ) ;
reader_pop_current_filename ( ) ;
proc_destroy ( ) ;
env_destroy ( ) ;
builtin_destroy ( ) ;
function_destroy ( ) ;
complete_destroy ( ) ;
reader_destroy ( ) ;
parser_destroy ( ) ;
wutil_destroy ( ) ;
common_destroy ( ) ;
intern_free_all ( ) ;
return res ;
}