]> git.jsancho.org Git - gacela.git/blobdiff - src/gacela.c
Resolving little bugs.
[gacela.git] / src / gacela.c
index 489d8c622897b8ad365c35b21898d42579f1afc5..af78da97433302a1a775cd16ffdbb95fe72972a0 100644 (file)
 #include "gacela_GL.h"
 #include "gacela_FTGL.h"
 
-// Generic variables
+// Global variables
 int ctrl_c = 0;
+int pid = 0;
+char *history_path = NULL;
+
 
 static int
 find_matching_paren (int k)
@@ -114,11 +117,18 @@ ctrl_c_handler (int signum)
   printf ("ERROR: User interrupt\nABORT: (signal)\n");
   ctrl_c = 1;
 }
-     
+
+void
+child_dies_handler (int signum)
+{
+  write_history (history_path);
+  exit (0);
+}
+
 static void
 init_gacela_client ()
 {
-  struct sigaction new_action;
+  struct sigaction ctrl_c_action, child_dies_action;
 
   // init bouncing parens
   rl_bind_key (')', match_paren);
@@ -126,11 +136,21 @@ init_gacela_client ()
   rl_bind_key ('}', match_paren);
 
   // SIGINT
-  new_action.sa_handler = ctrl_c_handler;
-  sigemptyset (&new_action.sa_mask);
-  new_action.sa_flags = 0;
+  ctrl_c_action.sa_handler = ctrl_c_handler;
+  sigemptyset (&ctrl_c_action.sa_mask);
+  ctrl_c_action.sa_flags = 0;
+
+  sigaction (SIGINT, &ctrl_c_action, NULL);
+
+  // SIGALRM
+  if (pid != 0) {
+    child_dies_action.sa_handler = child_dies_handler;
+    sigemptyset (&child_dies_action.sa_mask);
+    child_dies_action.sa_flags = 0;
+
+    sigaction (SIGALRM, &child_dies_action, NULL);
+  }
 
-  sigaction (SIGINT, &new_action, NULL);
 }
 
 int
@@ -146,7 +166,23 @@ opened_parens (char *line, int k)
   else if (k == '}') c = '{';
 
   for (i = 0; i < strlen (line); i++) {
-    if (line[i] == c)
+    // Is the current character part of a character literal?
+    if (i + 2 >= strlen (line)
+       && line[i] == '#'
+       && line[i + 1] == '\\')
+      i = i + 2;
+    else if (line[i] == '"') {
+      // Skip over a string literal
+      for (i++; i < strlen (line); i++)
+       if (line[i] == '"'
+           && line[i - 1] != '\\')
+             break;
+    }
+    else if (line[i] == ';') {
+      // Comment until endline
+      break;
+    }
+    else if (line[i] == c)
       opened++;
     else if (line[i] == k)
       opened--;
@@ -160,8 +196,7 @@ gacela_client (SCM rec_channel, SCM send_channel)
 {
   int n;
   SCM buffer;
-  char *line, *line_for_sending;
-  char *history_path;
+  char *line = NULL, *line_for_sending = NULL;
   int opened = 0;
 
   // Command line
@@ -176,15 +211,28 @@ gacela_client (SCM rec_channel, SCM send_channel)
     else
       line = readline ("gacela> ");
 
+    if (!line) break;
+
     opened += opened_parens (line, ')');
     ctrl_c = 0;
-    if (!line) break;
+
     if (line && *line)
       {
        add_history (line);
-       if (opened == 0) {
-         scm_write (scm_from_locale_string (line), send_channel);
+       if (line_for_sending == NULL) {
+         line_for_sending = strdup (line);
+       }
+       else {
+         line_for_sending = realloc (line_for_sending, strlen (line_for_sending) + strlen (line) + 2);
+         line_for_sending = strcat (line_for_sending, "\n");
+         line_for_sending = strcat (line_for_sending, line);
+       }
+
+       if (opened <= 0) {
+         scm_write (scm_from_locale_string (line_for_sending), send_channel);
          scm_force_output (send_channel);
+         free (line_for_sending);
+         line_for_sending = NULL;
 
          while (scm_char_ready_p (rec_channel) == SCM_BOOL_F) {
            if (ctrl_c) break;
@@ -280,7 +328,6 @@ main (int argc, char *argv[])
   int port = 0;
   int i;
   SCM fd1, fd2;
-  int pid;
 
   // Checking arguments
   for (i = 1; i < argc; i++) {
@@ -318,6 +365,7 @@ main (int argc, char *argv[])
       scm_close (SCM_CDR (fd2));
       init_gacela (dirname (argv[0]));
       start_local_server (scm_cons (SCM_CAR (fd2), SCM_CDR (fd1)));
+      kill (getppid (), SIGALRM);
     }
     else {
       scm_close (SCM_CDR (fd1));