/* Jimsh - An interactive shell for Jim * Copyright 2005 Salvatore Sanfilippo * Copyright 2009 Steve Bennett * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * A copy of the license is also included in the source distribution * of Jim, as a TXT file name called LICENSE. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "jim.h" /* JimGetExePath try to get the absolute path of the directory * of the jim binary, in order to add this path to the library path. * Likely shipped libraries are in the same path too. */ #ifndef JIM_ANSIC /* A bit complex on POSIX */ #include static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0) { char path[JIM_PATH_LEN+1]; /* Check if the executable was called with an absolute pathname */ if (argv0[0] == '/') { char *p; strncpy(path, argv0, JIM_PATH_LEN); p = strrchr(path, '/'); *(p+1) = '\0'; return Jim_NewStringObj(interp, path, -1); } else { char cwd[JIM_PATH_LEN+1]; char base[JIM_PATH_LEN+1], *p; int l; strncpy(base, argv0, JIM_PATH_LEN); if (getcwd(cwd, JIM_PATH_LEN) == NULL) { return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1); } l = strlen(cwd); if (l > 0 && cwd[l-1] == '/') cwd[l-1] = '\0'; p = strrchr(base, '/'); if (p == NULL) base[0] = '\0'; else if (p != base) *p = '\0'; sprintf(path, "%s/%s", cwd, base); l = strlen(path); if (l > 2 && path[l-2] == '/' && path[l-1] == '.') path[l-1] = '\0'; return Jim_NewStringObj(interp, path, -1); } } #else /* JIM_ANSIC */ /* ... and impossible with just ANSI C */ static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0) { JIM_NOTUSED(argv0); return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1); } #endif /* JIM_ANSIC */ static void JimLoadJimRc(Jim_Interp *interp) { const char *home; char buf [JIM_PATH_LEN+1]; const char *names[] = {".jimrc", "jimrc.tcl", NULL}; int i; FILE *fp; if ((home = getenv("HOME")) == NULL) return; for (i = 0; names[i] != NULL; i++) { if (strlen(home)+strlen(names[i])+1 > JIM_PATH_LEN) continue; sprintf(buf, "%s/%s", home, names[i]); if ((fp = fopen(buf, "r")) != NULL) { fclose(fp); if (Jim_EvalFile(interp, buf) != JIM_OK) { Jim_PrintErrorMessage(interp); } return; } } } static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) { int n; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); /* Populate argv global var */ for (n = 0; n < argc; n++) { Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); Jim_ListAppendElement(interp, listObj, obj); } Jim_SetVariableStr(interp, "argv", listObj); } int main(int argc, char *const argv[]) { int retcode; Jim_Interp *interp; Jim_Obj *listObj; /* Create and initialize the interpreter */ interp = Jim_CreateInterp(); Jim_RegisterCoreCommands(interp); /* Register static extensions */ if (Jim_InitStaticExtensions(interp) != JIM_OK) { Jim_PrintErrorMessage(interp); } /* Append the path where the executed Jim binary is contained * in the jim_libpath list. */ listObj = Jim_GetVariableStr(interp, JIM_LIBPATH, JIM_NONE); if (Jim_IsShared(listObj)) listObj = Jim_DuplicateObj(interp, listObj); Jim_ListAppendElement(interp, listObj, JimGetExePath(interp, argv[0])); Jim_SetVariableStr(interp, JIM_LIBPATH, listObj); Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]); if (argc == 1) { Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1"); JimSetArgv(interp, 0, NULL); JimLoadJimRc(interp); retcode = Jim_InteractivePrompt(interp); } else { Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "0"); if (argc > 2 && strcmp(argv[1], "-e") == 0) { JimSetArgv(interp, argc - 3, argv + 3); retcode = Jim_Eval(interp, argv[2]); } else { Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); JimSetArgv(interp, argc - 2, argv + 2); retcode = Jim_EvalFile(interp, argv[1]); } if (retcode == JIM_ERR) { Jim_PrintErrorMessage(interp); } } if (retcode == JIM_OK) { retcode = 0; } else if (retcode == JIM_EXIT) { retcode = interp->exitCode; } else { retcode = 1; } Jim_FreeInterp(interp); return retcode; }