/* -*- mode: C; mode: fold; -*- */ /* Copyright (c) 1992, 1998, 2000, 2002, 2003, 2004, 2005, 2006 John E. Davis * This file is part of JED editor library source. * * You may distribute this file under the terms the GNU General Public * License. See the file COPYING for more information. */ #include "config.h" #include "jed-feat.h" /*{{{ Include Files */ #ifdef __WIN32__ /* This needs to go first before stdio is included. */ # include # if !defined(__CYGWIN32__) # define sleep Sleep # endif #endif #include #include #include "jdmacros.h" #ifdef HAVE_STDLIB_H # include #endif #ifdef REAL_UNIX_SYSTEM # include # include #endif #include #ifdef HAVE_UNISTD_H # include #endif #include #include #ifdef __unix__ # ifdef SYSV # include # include # endif # include #endif #ifdef __MSDOS__ # include # if !defined(__WATCOMC__) # include # ifdef __BORLANDC__ extern unsigned _stklen = 10000U; # endif # else # include # endif #endif #if (defined(__WIN32__) && !defined(__CYGWIN32__)) || defined(__IBMC__) # include # include #endif #if defined(__DECC) && defined(VMS) #include #include #endif #ifndef O_RDWR #ifndef VMS # include #endif #endif #include "file.h" #include "buffer.h" #include "display.h" #include "sysdep.h" #include "sig.h" #include "misc.h" #include "keymap.h" #include "screen.h" #include "ledit.h" #include "search.h" #include "text.h" #include "hooks.h" #include "paste.h" #include "version.h" #include "indent.h" #include "colors.h" #ifdef __WIN32__ # include "win32.h" #endif /*}}}*/ int Jed_Secure_Mode; int Jed_Load_Quietly = 0; #if JED_HAS_UTF8_SUPPORT int Jed_UTF8_Mode; #endif char Jed_Root_Dir [JED_MAX_PATH_LEN]; typedef struct /*{{{*/ { jmp_buf b; } /*}}}*/ jmp_buf_struct; extern jmp_buf_struct Jump_Buffer, *Jump_Buffer_Ptr; int Batch = 0; #ifdef MSWINDOWS static char *get_win32_root(void) { static char base_path[JED_MAX_PATH_LEN]; char *p; base_path[0] = 0; if (GetModuleFileName(NULL, base_path, JED_MAX_PATH_LEN-10) > 0) { /* drop file name */ p = strrchr(base_path, '\\'); if (p != NULL) { *p = '\0'; /* drop also 'bin' */ p = strrchr(base_path, '\\'); if (p != NULL) *p = '\0'; } } return base_path; } #endif static void set_jed_root (char *pgm) { char *jr, *jl; char jed_lib [JED_MAX_PATH_LEN + 1]; *jed_lib = 0; #ifdef VMS jr = "JED_ROOT:"; #else jr = (char *) getenv("JED_ROOT"); #endif #ifdef JED_ROOT if ((jr == NULL) && (file_status(JED_ROOT) == 2)) { jr = JED_ROOT; } #endif #ifdef MSWINDOWS if (jr == NULL) jr = get_win32_root (); #endif if (jr != NULL) { strcpy (Jed_Root_Dir, jr); strcpy (jed_lib, jr); #ifndef VMS fixup_dir (jed_lib); strcat (jed_lib, "lib"); #else strcat(jed_lib, "[lib]"); #endif } jl = (char *) getenv("JED_LIBRARY"); if (jl == NULL) { if (*jed_lib == 0) { unsigned int len; jl = extract_file (pgm); len = (unsigned int) (jl - pgm); strncpy (jed_lib, pgm, len); jed_lib [len] = 0; } } else strcpy(jed_lib, jl); Jed_Library = SLang_create_slstring (jed_lib); if (Jed_Library == NULL) exit_error ("Out of memory", 0); } void (*X_Init_Global_Structures_Hook)(void); int Stdin_Is_TTY; int _Jed_Startup_Argc; char **_Jed_Startup_Argv; static void script_usage (void) { fprintf (stderr, "Running jed in script mode requires one of the following forms:\n"); fprintf (stderr, "Usage: jed-script SCRIPT_FILE [args...]\n"); fprintf (stderr, "Usage: jed --script SCRIPT_FILE [args...]\n"); } static int main_initialize (int argc, char **argv) { char *cmd_hook = ".()command_line_hook"; int i, fd; char *script_file; _Jed_Startup_Argv = argv; _Jed_Startup_Argc = argc; #ifdef __EMX__ _response(&argc, &argv); _wildcard(&argc, &argv); #endif #ifdef WINDOWS if (NULL == getenv ("JED_ROOT")) { MessageBox(NULL, "RTFM: You must set the JED_ROOT environment variable.\nAborting\n", "Jed", MB_ICONEXCLAMATION | MB_TASKMODAL | MB_SETFOREGROUND | MB_OK); exit(1); } #endif #if JED_HAS_DISPLAY_TABLE for (i = 0; i < 256; i++) Output_Display_Table[i] = i; #endif if ((argc > 1) && !strcmp (argv[1], "-secure")) { Jed_Secure_Mode = 1; argc--; argv[1] = argv[0]; argv++; } /* If this hook is defined, let it peel off what ever arguments it wants. It should return the number of remaining arguments */ if (X_Argc_Argv_Hook != NULL) { i = (*X_Argc_Argv_Hook)(argc, argv) - 1; argv[i] = argv[0]; argc -= i; argv += i; } /* If jed-script is a symbolic link to jed, then treat this as equivalent * to jed -script args... */ script_file = NULL; if (0 == strcmp (extract_file (argv[0]), "jed-script")) { Batch = 2; SLang_Traceback = 1; Jed_Load_Quietly = 1; if (argc > 1) script_file = argv[1]; else { script_usage (); return -1; } argv++; /* make argv[0] the name of the script */ argc--; } else if (argc > 1) { char *argv1 = argv[1]; /* Allow, e.g., --batch */ if ((argv1[0] == '-') && (argv1[1] == '-')) argv1++; if (!strcmp(argv1, "-batch")) { Batch = 1; SLang_Traceback = 1; } else if (!strcmp(argv1, "-script")) { Batch = 2; SLang_Traceback = 1; Jed_Load_Quietly = 1; if (argc > 2) script_file = argv[2]; } else if (!strcmp (argv1, "-help")) { Batch = 1; SLang_Traceback = 1; Jed_Load_Quietly = 1; } } #if JED_HAS_UTF8_SUPPORT Jed_UTF8_Mode = SLutf8_enable (-1); if (Jed_UTF8_Mode == 0) { char *u = getenv ("JED_UTF8"); if (u != NULL) { if ((0 == strcmp (u, "1")) || (0 == strcmp (u, "FORCE"))) { Jed_UTF8_Mode = 1; /* force jed to use UTF-8 internally */ SLsmg_utf8_enable (1); SLinterp_utf8_enable (1); } if (0 == strcmp (u, "FORCE")) SLtt_utf8_enable (1); } } #endif #if JED_HAS_UTF8_SUPPORT if (Jed_UTF8_Mode) define_word ("\\w"); else { #endif #ifdef __MSDOS__ define_word("0-9a-zA-Z\200-\232\240-\245\341-\353"); #else define_word("0-9a-zA-Z\300-\326\330-\366\370-\377"); #endif #if JED_HAS_UTF8_SUPPORT } #endif (*tt_get_terminfo) (); fd = 2; /* 2 is stderr, assume it is ok */ #if defined(REAL_UNIX_SYSTEM) && !defined(__APPLE__) if (Batch == 0) { int dev_tty_fd; if ((dev_tty_fd = open("/dev/tty", O_RDWR)) >= 0) { fd = dev_tty_fd; while (-1 == dup2(fd, 2)) /* tty uses 2 as the descriptor */ { # ifdef EINTR if (errno == EINTR) continue; # endif fd = 2; break; } close (dev_tty_fd); } } #endif /* REAL_UNIX_SYSTEM */ #if defined(__WIN32__) if (-1 == jed_init_w32_support ()) return -1; #endif if (-1 == init_tty ()) exit_error ("Unable to initialize tty.", 0); jed_init_display (); /* sets up virtual screen */ (*tt_set_mono) (JMESSAGE_COLOR, NULL, 0); (*tt_set_mono) (JERROR_COLOR, NULL, SLTT_BOLD_MASK); (*tt_set_mono) (JDOLLAR_COLOR, NULL, SLTT_BOLD_MASK); (*tt_set_mono) (JDOTS_COLOR, NULL, SLTT_BOLD_MASK); (*tt_set_mono) (JMENU_CHAR_COLOR, NULL, SLTT_BOLD_MASK); (*tt_set_mono) (JMENU_SELECTION_COLOR, NULL, SLTT_REV_MASK|SLTT_BOLD_MASK); (*tt_set_mono) (JMENU_POPUP_COLOR, NULL, 0); (*tt_set_mono) (JMENU_SELECTED_CHAR_COLOR, NULL, SLTT_BOLD_MASK); (void) jed_set_color (JMENU_SHADOW_COLOR, "blue", "black"); (void) jed_set_color (JMENU_POPUP_COLOR, "lightgray", "blue"); (*tt_set_mono) (JMENU_SHADOW_COLOR, NULL, 0); (void) jed_set_color (JMENU_SHADOW_COLOR, "blue", "black"); init_syntax_tables (); /* This order here is crucial! */ init_keymaps(); if (NULL == (CBuf = make_buffer(NULL, NULL, NULL))) { exit_error("main: Allocation Failure", 0); } CLine = NULL; init_minibuffer(); set_file_modes(); /* what if someone pipes something to jed, allow it unless if is a * jed script. */ if (Stdin_Is_TTY == 0) Stdin_Is_TTY = isatty (0); if ((Stdin_Is_TTY == 0) && (Batch != 2)) /* 1 if stdin is a terminal, 0 otherwise */ { set_buffer("*stdin*"); read_file_pointer(fileno(stdin)); bob(); fclose(stdin); dup2(fd, 0); } if (CLine == NULL) make_line(25); bol (); window_buffer(CBuf); #if !defined(IBMPC_SYSTEM) && !defined(VMS) init_signals(); #endif (void) SLang_set_argc_argv (argc, argv); if ((0 != jed_ns_load_file("site", NULL)) && Batch) return -1; if (Batch) Ignore_User_Abort = 0; if (Batch == 2) { if (script_file == NULL) { script_usage (); return -1; } #if SLANG_VERSION >= 20000 { char *file = SLpath_find_file_in_path (".", script_file); if (file == NULL) { fprintf (stderr, "%s not found.\n", script_file); return -1; } if (0 != SLns_load_file (file, NULL)) { SLfree (file); return -1; } SLfree (file); } #else if (0 != jed_ns_load_file (script_file, NULL)) return -1; #endif if (-1 == SLang_run_hooks ("jedscript_main", 0)) return -1; } else { if (SLang_is_defined(cmd_hook + 3)) { SLang_run_hooks(cmd_hook + 3, 0); if (SLang_get_error () && Batch) return -1; /* This has the effect of removing the memory that cmd_hook * is using. */ SLang_load_string (cmd_hook); } else if (!SLang_get_error () && (argc > 2)) { find_file_in_window(argv[2]); } } if (SLang_get_error () && Batch) return -1; /* after we have possible loaded key definitions, we can fix up * the minibuffer map. This way user definitions are used. */ jed_setup_minibuffer_keymap (); return 0; } int main(int argc, char **argv) /*{{{*/ { if (SLang_Version < SLANG_VERSION) { fprintf (stderr, "***Warning: Executable compiled against S-Lang %d but linked to %d\n", SLANG_VERSION, SLang_Version); fflush (stderr); sleep (2); } set_jed_root (argv[0]); if (argc > 1) { if (!strcmp (argv[1], "--version")) { jed_show_version (stdout); fprintf (stdout, "\nUsing JED_ROOT=%s\n", Jed_Root_Dir); exit (0); } } Jump_Buffer_Ptr = &Jump_Buffer; /* incase something goes wrong before we even get started... */ if (setjmp(Jump_Buffer_Ptr->b) != 0) { /* hmm.... just exit I guess */ exit_error("main: Fatal Error", 0); exit (1); } if (0 != main_initialize (argc, argv)) { jed_reset_display(); reset_tty(); return SLang_get_error (); } /* edit_loop */ if (!Batch) jed(); /* never returns */ /* exit_error ("Batch End with no exit", 0); */ jed_reset_display(); reset_tty(); return SLang_get_error (); } /*}}}*/