Minor cleanup in JimParseVar()
[jimtcl.git] / jim-interactive.c
blob90976ce81e96f5673292b019fba21a9b75aa5c95
1 #include <errno.h>
2 #include <string.h>
3 #include "jim.h"
4 #include "jimautoconf.h"
6 #ifdef USE_LINENOISE
7 #include "linenoise.h"
8 #else
10 #define MAX_LINE_LEN 512
12 static char *linenoise(const char *prompt)
14 char *line = malloc(MAX_LINE_LEN);
16 fputs(prompt, stdout);
17 fflush(stdout);
19 if (fgets(line, MAX_LINE_LEN, stdin) == NULL) {
20 free(line);
21 return NULL;
23 return line;
25 #endif
27 int Jim_InteractivePrompt(Jim_Interp *interp)
29 int retcode = JIM_OK;
30 char *history_file = NULL;
31 #ifdef USE_LINENOISE
32 const char *home;
34 home = getenv("HOME");
35 if (home) {
36 int history_len = strlen(home) + sizeof("/.jim_history");
37 history_file = Jim_Alloc(history_len);
38 snprintf(history_file, history_len, "%s/.jim_history", home);
39 linenoiseHistoryLoad(history_file);
41 #endif
43 printf("Welcome to Jim version %d.%d" JIM_NL,
44 JIM_VERSION / 100, JIM_VERSION % 100);
45 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1");
47 while (1) {
48 Jim_Obj *scriptObjPtr;
49 const char *result;
50 int reslen;
51 char prompt[20];
52 const char *str;
54 if (retcode != 0) {
55 const char *retcodestr = Jim_ReturnCode(retcode);
57 if (*retcodestr == '?') {
58 snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode);
60 else {
61 snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr);
64 else {
65 prompt[0] = '\0';
67 strcat(prompt, ". ");
69 scriptObjPtr = Jim_NewStringObj(interp, "", 0);
70 Jim_IncrRefCount(scriptObjPtr);
71 while (1) {
72 char state;
73 int len;
74 char *line;
76 line = linenoise(prompt);
77 if (line == NULL) {
78 if (errno == EINTR) {
79 continue;
81 Jim_DecrRefCount(interp, scriptObjPtr);
82 goto out;
84 if (Jim_Length(scriptObjPtr) != 0) {
85 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
87 Jim_AppendString(interp, scriptObjPtr, line, -1);
88 free(line);
89 str = Jim_GetString(scriptObjPtr, &len);
90 if (len == 0) {
91 continue;
93 if (Jim_ScriptIsComplete(str, len, &state))
94 break;
96 snprintf(prompt, sizeof(prompt), "%c> ", state);
98 #ifdef USE_LINENOISE
99 if (strcmp(str, "h") == 0) {
100 /* built-in history command */
101 int i;
102 int len;
103 char **history = linenoiseHistory(&len);
104 for (i = 0; i < len; i++) {
105 printf("%4d %s\n", i + 1, history[i]);
107 Jim_DecrRefCount(interp, scriptObjPtr);
108 continue;
111 linenoiseHistoryAdd(Jim_String(scriptObjPtr));
112 linenoiseHistorySave(history_file);
113 #endif
114 retcode = Jim_EvalObj(interp, scriptObjPtr);
115 Jim_DecrRefCount(interp, scriptObjPtr);
119 if (retcode == JIM_EXIT) {
120 Jim_Free(history_file);
121 return JIM_EXIT;
123 if (retcode == JIM_ERR) {
124 Jim_MakeErrorMessage(interp);
126 result = Jim_GetString(Jim_GetResult(interp), &reslen);
127 if (reslen) {
128 printf("%s\n", result);
131 out:
132 Jim_Free(history_file);
133 return JIM_OK;