/* -*-c-*- -------------- mixvm_loop.c : * Implementation of mix vm command loop. * ------------------------------------------------------------------ * $Id: mixvm_loop.c,v 1.10 2002/04/08 01:59:38 jao Exp $ * ------------------------------------------------------------------ * Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. * * 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. * */ #include #include #include #include #include #include #include #ifdef MAKE_GUILE #include #endif #include "mixvm_command.h" #include "mixvm_loop.h" #ifdef HAVE_LIBHISTORY # include #else # define add_history(x) ((void)0) #endif #ifdef HAVE_LIBREADLINE # include #else /* !HAVE_LIBREADLINE */ static char * readline (char *prompt) { enum {LINE_LEN = 256}; char *line = g_new (char, LINE_LEN); printf ("%s", prompt); return fgets (line, LINE_LEN, stdin); } #endif /* HAVE_LIBREADLINE */ /* A static variable for holding the line. */ static char *line_read = (char *)NULL; static char *PROMPT = NULL; static const char *CONFIG_FILE_ = "mixvm.config"; static const char *PROMPT_KEY_ = "Prompt"; /* Read a string, and return a pointer to it. Returns NULL on EOF. */ static char * rl_gets () { /* If the buffer has already been allocated, return the memory to the free pool. */ if (line_read) { g_free (line_read); line_read = (char *)NULL; } /* Get a line from the user. */ line_read = readline ((char *)PROMPT); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) add_history (line_read); return (line_read); } /* The main command loop of the virtual machine */ static mix_config_t *config_ = NULL; static mix_vm_cmd_dispatcher_t * init_mixvm_ (const gchar *file, gboolean use_emacs) { static const gchar *HISTORY_FILE = "mixvm.history"; static gint HISTORY_SIZE = 100; const char *prompt = NULL; config_ = mix_config_new (NULL, CONFIG_FILE_); mix_config_set_autosave (config_, TRUE); if (!mix_config_get_history_file (config_)) mix_config_set_history_file (config_, HISTORY_FILE); if (mix_config_get_history_size (config_) == 0) mix_config_set_history_size (config_, HISTORY_SIZE); prompt = mix_config_get (config_, PROMPT_KEY_); if (!prompt) prompt = "MIX > "; mix_vmloop_set_prompt (prompt); return mixvm_cmd_init (config_, (char *)file, use_emacs); } void mix_vmloop_set_prompt (const gchar *prompt) { if (prompt) { if (PROMPT) g_free (PROMPT); if (prompt[0] == '"') prompt++; PROMPT = g_strdup (prompt); if (PROMPT[strlen (PROMPT) - 1] == '"') PROMPT[strlen (PROMPT) - 1] = 0; mix_config_update (config_, PROMPT_KEY_, PROMPT); } } static void loop_ (int argc, char *argv[]) { while ( mixvm_cmd_exec (rl_gets ()) ) ; mix_config_delete (config_); } void mix_vmloop (int argc, char *argv[], gboolean initfile, const gchar *file, gboolean use_emacs) { #ifdef MAKE_GUILE mix_vm_cmd_dispatcher_t *dis = init_mixvm_ (file, use_emacs); mixguile_init (argc, argv, initfile, loop_, dis); #else (void) init_mixvm_ (file, use_emacs); loop_ (argc, argv); #endif } /* run a program and exit */ void mix_vmrun (const gchar *code_file, gboolean dump, gboolean ptime) { gchar *time_cmd = ptime? g_strdup("stime on") : g_strdup("stime off"); gchar *run_cmd = g_strdup("run"); gchar *dump_cmd = dump? g_strdup("pall") : NULL; gboolean result; init_mixvm_ (code_file, FALSE); result = mixvm_cmd_exec (time_cmd) && mixvm_cmd_exec (run_cmd); if (result && dump) mixvm_cmd_exec (dump_cmd); mix_config_delete (config_); g_free(time_cmd); g_free(run_cmd); if (dump_cmd) g_free(dump_cmd); }