try: fix use of catch/uplevel
[jimtcl.git] / jim-interactive.c
blobf07eea1974500a4629cdbecc8fcb6436863890b6
1 #include <errno.h>
2 #include <string.h>
4 #include "jimautoconf.h"
5 #include <jim.h>
7 #ifdef USE_LINENOISE
8 #include <unistd.h>
9 #include "linenoise.h"
10 #else
11 #define MAX_LINE_LEN 512
12 #endif
14 /**
15 * Returns an allocated line, or NULL if EOF.
17 char *Jim_HistoryGetline(const char *prompt)
19 #ifdef USE_LINENOISE
20 return linenoise(prompt);
21 #else
22 int len;
23 char *line = malloc(MAX_LINE_LEN);
25 fputs(prompt, stdout);
26 fflush(stdout);
28 if (fgets(line, MAX_LINE_LEN, stdin) == NULL) {
29 free(line);
30 return NULL;
32 len = strlen(line);
33 if (len && line[len - 1] == '\n') {
34 line[len - 1] = '\0';
36 return line;
37 #endif
40 void Jim_HistoryLoad(const char *filename)
42 #ifdef USE_LINENOISE
43 linenoiseHistoryLoad(filename);
44 #endif
47 void Jim_HistoryAdd(const char *line)
49 #ifdef USE_LINENOISE
50 linenoiseHistoryAdd(line);
51 #endif
54 void Jim_HistorySave(const char *filename)
56 #ifdef USE_LINENOISE
57 linenoiseHistorySave(filename);
58 #endif
61 void Jim_HistoryShow(void)
63 #ifdef USE_LINENOISE
64 /* built-in history command */
65 int i;
66 int len;
67 char **history = linenoiseHistory(&len);
68 for (i = 0; i < len; i++) {
69 printf("%4d %s\n", i + 1, history[i]);
71 #endif
74 int Jim_InteractivePrompt(Jim_Interp *interp)
76 int retcode = JIM_OK;
77 char *history_file = NULL;
78 #ifdef USE_LINENOISE
79 const char *home;
81 home = getenv("HOME");
82 if (home && isatty(STDIN_FILENO)) {
83 int history_len = strlen(home) + sizeof("/.jim_history");
84 history_file = Jim_Alloc(history_len);
85 snprintf(history_file, history_len, "%s/.jim_history", home);
86 Jim_HistoryLoad(history_file);
88 #endif
90 printf("Welcome to Jim version %d.%d\n",
91 JIM_VERSION / 100, JIM_VERSION % 100);
92 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1");
94 while (1) {
95 Jim_Obj *scriptObjPtr;
96 const char *result;
97 int reslen;
98 char prompt[20];
99 const char *str;
101 if (retcode != 0) {
102 const char *retcodestr = Jim_ReturnCode(retcode);
104 if (*retcodestr == '?') {
105 snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode);
107 else {
108 snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr);
111 else {
112 prompt[0] = '\0';
114 strcat(prompt, ". ");
116 scriptObjPtr = Jim_NewStringObj(interp, "", 0);
117 Jim_IncrRefCount(scriptObjPtr);
118 while (1) {
119 char state;
120 int len;
121 char *line;
123 line = Jim_HistoryGetline(prompt);
124 if (line == NULL) {
125 if (errno == EINTR) {
126 continue;
128 Jim_DecrRefCount(interp, scriptObjPtr);
129 retcode = JIM_OK;
130 goto out;
132 if (Jim_Length(scriptObjPtr) != 0) {
133 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
135 Jim_AppendString(interp, scriptObjPtr, line, -1);
136 free(line);
137 str = Jim_GetString(scriptObjPtr, &len);
138 if (len == 0) {
139 continue;
141 if (Jim_ScriptIsComplete(str, len, &state))
142 break;
144 snprintf(prompt, sizeof(prompt), "%c> ", state);
146 #ifdef USE_LINENOISE
147 if (strcmp(str, "h") == 0) {
148 /* built-in history command */
149 Jim_HistoryShow();
150 Jim_DecrRefCount(interp, scriptObjPtr);
151 continue;
154 Jim_HistoryAdd(Jim_String(scriptObjPtr));
155 if (history_file) {
156 Jim_HistorySave(history_file);
158 #endif
159 retcode = Jim_EvalObj(interp, scriptObjPtr);
160 Jim_DecrRefCount(interp, scriptObjPtr);
162 if (retcode == JIM_EXIT) {
163 retcode = JIM_EXIT;
164 break;
166 if (retcode == JIM_ERR) {
167 Jim_MakeErrorMessage(interp);
169 result = Jim_GetString(Jim_GetResult(interp), &reslen);
170 if (reslen) {
171 printf("%s\n", result);
174 out:
175 Jim_Free(history_file);
176 return retcode;