zlib: Don't use PASTE for INTMAX error messages
[jimtcl.git] / jim-interactive.c
blob78f547071c51d44f904590832a00c1a81be01312
1 #include <errno.h>
2 #include <string.h>
4 #include "jimautoconf.h"
5 #include <jim.h>
7 #ifdef USE_LINENOISE
8 #ifdef HAVE_UNISTD_H
9 #include <unistd.h>
10 #endif
11 #include "linenoise.h"
12 #else
13 #define MAX_LINE_LEN 512
14 #endif
16 /**
17 * Returns an allocated line, or NULL if EOF.
19 char *Jim_HistoryGetline(const char *prompt)
21 #ifdef USE_LINENOISE
22 return linenoise(prompt);
23 #else
24 int len;
25 char *line = malloc(MAX_LINE_LEN);
27 fputs(prompt, stdout);
28 fflush(stdout);
30 if (fgets(line, MAX_LINE_LEN, stdin) == NULL) {
31 free(line);
32 return NULL;
34 len = strlen(line);
35 if (len && line[len - 1] == '\n') {
36 line[len - 1] = '\0';
38 return line;
39 #endif
42 void Jim_HistoryLoad(const char *filename)
44 #ifdef USE_LINENOISE
45 linenoiseHistoryLoad(filename);
46 #endif
49 void Jim_HistoryAdd(const char *line)
51 #ifdef USE_LINENOISE
52 linenoiseHistoryAdd(line);
53 #endif
56 void Jim_HistorySave(const char *filename)
58 #ifdef USE_LINENOISE
59 linenoiseHistorySave(filename);
60 #endif
63 void Jim_HistoryShow(void)
65 #ifdef USE_LINENOISE
66 /* built-in history command */
67 int i;
68 int len;
69 char **history = linenoiseHistory(&len);
70 for (i = 0; i < len; i++) {
71 printf("%4d %s\n", i + 1, history[i]);
73 #endif
76 int Jim_InteractivePrompt(Jim_Interp *interp)
78 int retcode = JIM_OK;
79 char *history_file = NULL;
80 #ifdef USE_LINENOISE
81 const char *home;
83 home = getenv("HOME");
84 if (home && isatty(STDIN_FILENO)) {
85 int history_len = strlen(home) + sizeof("/.jim_history");
86 history_file = Jim_Alloc(history_len);
87 snprintf(history_file, history_len, "%s/.jim_history", home);
88 Jim_HistoryLoad(history_file);
90 #endif
92 printf("Welcome to Jim version %d.%d\n",
93 JIM_VERSION / 100, JIM_VERSION % 100);
94 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1");
96 while (1) {
97 Jim_Obj *scriptObjPtr;
98 const char *result;
99 int reslen;
100 char prompt[20];
102 if (retcode != JIM_OK) {
103 const char *retcodestr = Jim_ReturnCode(retcode);
105 if (*retcodestr == '?') {
106 snprintf(prompt, sizeof(prompt) - 3, "[%d] . ", retcode);
108 else {
109 snprintf(prompt, sizeof(prompt) - 3, "[%s] . ", retcodestr);
112 else {
113 strcpy(prompt, ". ");
116 scriptObjPtr = Jim_NewStringObj(interp, "", 0);
117 Jim_IncrRefCount(scriptObjPtr);
118 while (1) {
119 char state;
120 char *line;
122 line = Jim_HistoryGetline(prompt);
123 if (line == NULL) {
124 if (errno == EINTR) {
125 continue;
127 Jim_DecrRefCount(interp, scriptObjPtr);
128 retcode = JIM_OK;
129 goto out;
131 if (Jim_Length(scriptObjPtr) != 0) {
132 /* Line continuation */
133 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
135 Jim_AppendString(interp, scriptObjPtr, line, -1);
136 free(line);
137 if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
138 break;
140 snprintf(prompt, sizeof(prompt), "%c> ", state);
142 #ifdef USE_LINENOISE
143 if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
144 /* built-in history command */
145 Jim_HistoryShow();
146 Jim_DecrRefCount(interp, scriptObjPtr);
147 continue;
150 Jim_HistoryAdd(Jim_String(scriptObjPtr));
151 if (history_file) {
152 Jim_HistorySave(history_file);
154 #endif
155 retcode = Jim_EvalObj(interp, scriptObjPtr);
156 Jim_DecrRefCount(interp, scriptObjPtr);
158 if (retcode == JIM_EXIT) {
159 break;
161 if (retcode == JIM_ERR) {
162 Jim_MakeErrorMessage(interp);
164 result = Jim_GetString(Jim_GetResult(interp), &reslen);
165 if (reslen) {
166 printf("%s\n", result);
169 out:
170 Jim_Free(history_file);
171 return retcode;