* make FvwmConsole build with system readline on Mac OS X (BSD libedit)
[fvwm.git] / modules / FvwmConsole / getline.c
blob34214ae4a4945785d76a53d032acdd76621da131
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "config.h"
19 #include "FvwmConsole.h"
21 #ifdef HAVE_READLINE
22 #include <readline/readline.h>
23 #include <readline/history.h>
24 #define fvwm_rl_bind_key(x, y) rl_bind_key(x, y)
25 #define fvwm_readline(x) readline(x)
26 #define fvwm_add_history(cmd) add_history(cmd)
27 #define fvwm_stifle_history(x) stifle_history(x)
28 #define fvwm_read_history(x) read_history(x)
29 #define fvwm_write_history(x) write_history(x)
30 #ifdef HAVE_GNU_READLINE
31 #define fvwm_append_history(x, y) append_history(x, y)
32 #define fvwm_history_truncate_file(x, y) history_truncate_file(x, y)
33 #define fvwm_read_history_range(x, y, z) read_history_range(x, y, z)
34 #else
35 #define fvwm_append_history(x, y) -1
36 #define fvwm_history_truncate_file(x, y) -1
37 #define fvwm_read_history_range(x, y, z) -1
38 #endif
39 #define USE_READLINE 1
40 #else
41 #define fvwm_rl_bind_key(x, y) -1
42 #define fvwm_readline(x) NULL
43 #define fvwm_add_history(cmd)
44 #define fvwm_append_history(x, y) -1
45 #define fvwm_history_truncate_file(x, y) -1
46 #define fvwm_read_history_range(x, y, z) -1
47 #define fvwm_stifle_history(x)
48 #define fvwm_read_history(x) -1
49 #define fvwm_write_history(x) -1
50 #define USE_READLINE 0
51 #endif
53 static char cmd[MAX_COMMAND_SIZE];
54 static char *line = (char *)NULL;
55 static int done_init = 0;
56 static char *h_file;
58 char *get_line(void)
60 char *prompt;
61 int len;
62 char *home;
63 int fdh;
65 if (USE_READLINE == 0)
67 if (fgets(cmd, MAX_COMMAND_SIZE, stdin) == NULL)
69 return NULL;
72 return cmd;
74 /* If initialization hasn't been done, do it now:
75 * - We don't want TAB completion
77 if (!done_init)
79 (void)fvwm_rl_bind_key('\t', rl_insert);
80 /* get history from file */
81 home = getenv("FVWM_USERDIR");
82 h_file = safemalloc(strlen(home) + sizeof(HISTFILE) + 1);
83 strcpy(h_file, home);
84 strcat(h_file, HISTFILE);
85 fvwm_stifle_history(HISTSIZE);
86 if (access(h_file, F_OK) < 0)
88 /* if it doesn't exist create it */
89 fdh = creat(h_file, S_IRUSR | S_IWUSR);
90 if (fdh != -1)
92 close(fdh);
95 else
97 (void)fvwm_read_history(h_file);
99 done_init = 1;
101 /* Empty out the previous info */
102 len = 0;
103 *cmd = '\0';
104 prompt = PS1;
105 while (1)
107 int linelen = 0;
109 /* If the buffer has already been allocated, free the memory.
111 if (line != (char *)NULL)
113 free(line);
116 /* Get a line from the user. */
117 line = fvwm_readline(prompt);
118 if (line == NULL)
120 return NULL;
123 /* Make sure we have enough space for the new line */
124 linelen = strlen(line);
125 if (len + linelen > MAX_COMMAND_SIZE-2)
127 fprintf(
128 stderr, "line too long %d chars max %d \a\n",
129 len + linelen, MAX_COMMAND_SIZE - 2);
130 strncat(cmd, line, MAX_COMMAND_SIZE - len - 2);
131 fvwm_add_history(cmd);
132 break;
135 /* Copy the new line onto the end of the current line */
136 strcat(cmd, line);
137 /* If the current line doesn't end with a backslash, we're done
139 len = strlen(cmd);
140 if (cmd[len-1] != '\\')
142 break;
144 /* Otherwise, remove it and wait for more (add a space if
145 * needed) */
146 prompt = PS2;
147 cmd[len-1] =
148 (cmd[len-2] == ' ' || cmd[len-2] == '\t') ? '\0' : ' ';
150 /* If the command has any text in it, save it on the history. */
151 if (*cmd != '\0')
153 fvwm_add_history(cmd);
154 if (fvwm_append_history(1, h_file) == 0)
156 (void)fvwm_history_truncate_file(h_file, HISTSIZE);
158 else
160 (void)fvwm_write_history(h_file);
163 cmd[len] = '\n';
164 cmd[len+1] = '\0';
166 return cmd;