diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 306 |
1 files changed, 306 insertions, 0 deletions
@@ -0,0 +1,306 @@ +/* +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); + + eval( L"builtin cd /etc 2>/dev/null; . fish 2>/dev/null", 0, TOP ); + 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; +} |