/* ** File: hey_readline.c ** Desc: Contains the general hooks for reading a line ** Auth: Colm MacCarthaigh (colmmacc@redbrick.dcu.ie) ** Date: 5/9/01 ** ** $Id: hey_readline.c,v 1.2 2001/12/30 23:26:06 c-hey Exp $ */ /* ** this is some pretty complicated shit - but well worth it :) ** ** ANSI escapes rock! */ #include #include #include #include "hey_readline.h" #include "hey_edit.h" #include "hey_format.h" #include "hey_arg.h" #include "dyn_page.h" #include "config.h" #include "aux.h" #ifdef HAVE_LIBREADLINE /* readline includes */ #include #include #endif #define LINESIZE 128 /* Should be plenty */ /* are we currently editing ? */ static int hey_editing; #ifdef HAVE_LIBREADLINE /* the line we are currently on */ int hey_line = 0; /* the total number of lines */ int hey_linetotal = 0; /* has the last line been appended */ int hey_lastdone = 0; #endif /* the expanded prompt */ char *hey_rlprompt; /* initialise readline stuff */ void hey_readline_init() { #ifdef HAVE_LIBREADLINE /* every app should have this set */ rl_readline_name = "hey"; /* add our function names */ rl_add_defun("hey_carriage_return", hey_return, -1); rl_add_defun("hey_line_up", hey_lineup, -1); rl_add_defun("hey_line_down", hey_linedown, -1); rl_add_defun("hey_arrows", hey_arrows, -1); rl_add_defun("hey_return", hey_return, -1); /* tell readline where to find bindings */ rl_startup_hook = hey_bindkeys; #endif /* make sure prompt is set */ if((hey_rlprompt = hey_generate_prompt()) == NULL) { hey_rlprompt = strdup(""); } /* we are now editing */ hey_editing = 1; } /* we are done reading lines */ void hey_readline_fini() { /* we are done editing */ hey_editing = 0; /* the prompt can upset error messages */ if(strcmp(hey_rlprompt,"")) printf("\n"); /* leaks are bad */ free(hey_rlprompt); } /* actually read a line from standard input */ char *hey_readline(void) { #ifndef HAVE_LIBREADLINE static char line[LINESIZE]; #endif #ifdef HAVE_LIBREADLINE char *line; hey_line++; hey_linetotal++; hey_lastdone = 0; if((line = readline(hey_rlprompt)) == NULL) { return NULL; } #endif #ifndef HAVE_LIBREADLINE /* print the prompt */ printf("%s", hey_rlprompt); /* get the line */ if(!fgets(line,LINESIZE,stdin)) { return NULL; } /* chomp the line */ if (strlen(line) > 1) if (line[strlen(line) - 1] == '\n') line[strlen(line) -1] = '\0'; #endif /* test for EOF */ if(hey_eof != NULL) { if(!strcmp(line,hey_eof)) { return NULL; } } /* throw it back */ return line; } /* generate the hey prompt */ char *hey_generate_prompt(void) { char *username; hey_user *user; char *prompt_line; int count; char *ptr; #define MINIBUFSIZE 16 char mini_buffer[MINIBUFSIZE]; /* This code is my fault. Blame me :) */ if (hey_prompt) { /* Allocate initial space for the prompt_line */ if ((prompt_line = malloc(1)) == NULL) { perror_exit("hey: Out of Memory while allocating prompt_line\n"); } *prompt_line = '\0'; /* Format the username string */ /* Add the first user name we are heying */ /* there will always be one .... */ user = (hey_user *)g_listTraverse(hey_userlist); if (user) { username = strdup(user->name); } else { if((username = malloc(1)) == NULL) { perror_exit("hey: Out of Memory while allocating username\n"); } *username = '\0'; } /* Add additional names * If we have more than 4, we put in ... to show multiple users */ for (count = 1; count < hey_nousers ; count++) { if (count < hey_maxnames) { user = (hey_user *)g_listTraverse(NULL); username = m_strcat(username, " "); username = m_strcat(username, user->name); } else { username = m_strcat(username," ..."); break; } } /* dosome search and replace */ for (ptr = hey_prompt; *ptr; ptr++) { if (*ptr == '%') { switch(*(ptr + 1)) { case '%': prompt_line = m_strcat(prompt_line, "%"); ptr++; break; case 'u': case 'U': prompt_line = m_strcat(prompt_line, username); ptr++; break; case 'n': case 'N': snprintf(mini_buffer, MINIBUFSIZE, "%d", hey_nousers); prompt_line = m_strcat(prompt_line, mini_buffer); ptr++; break; default: snprintf(mini_buffer, MINIBUFSIZE, "%c", *ptr); prompt_line = m_strcat(prompt_line, mini_buffer); break; } } else { snprintf(mini_buffer, MINIBUFSIZE, "%c", *ptr); prompt_line = m_strcat(prompt_line, mini_buffer); } } free(username); } else { prompt_line = NULL; } return prompt_line; #undef MINIBUFSIZE } /* redisplays a hey's buffer after SIGCONT */ void hey_redisplay(void) { #ifndef HAVE_LIBREADLINE char * ptr; if(!hey_editing) return; if((ptr = dyn_pageRead(hey_page))) { do { printf("%s%s\n",hey_rlprompt,ptr); } while ((ptr = dyn_pageRead(NULL))); } printf("%s", hey_rlprompt); /* make sure it's all on screen */ fflush(stdout); #endif #ifdef HAVE_LIBREADLINE if(!hey_editing) return; hey_refresh(0, 0); #endif }