#include <assert.h>
#include <errno.h>
#include <time.h>
+#if defined(WIN32)
+/* sys/time - need is different */
+#else
+#include <sys/time.h> // for gettimeofday()
+#endif
#include "replacements.h"
* Utility functions
* ---------------------------------------------------------------------------*/
+static char *
+jim_vasprintf( const char *fmt, va_list ap )
+{
+#ifndef HAVE_VASPRINTF
+ /* yucky way */
+static char buf[2048];
+ vsnprintf( buf, sizeof(buf), fmt, ap );
+ /* garentee termination */
+ buf[sizeof(buf)-1] = 0;
+#else
+ char *buf;
+ vasprintf( &buf, fmt, ap );
+#endif
+ return buf;
+}
+
+static void
+jim_vasprintf_done( void *buf )
+{
+#ifndef HAVE_VASPRINTF
+ (void)(buf);
+#else
+ free(buf);
+#endif
+}
+
+
/*
* Convert a string to a jim_wide INTEGER.
* This function originates from BSD.
StringAppendString(objPtr, str, len);
}
+void Jim_AppendString_sprintf( Jim_Interp *interp, Jim_Obj *objPtr, const char *fmt, ... )
+{
+ char *buf;
+ va_list ap;
+
+ va_start( ap, fmt );
+ buf = jim_vasprintf( fmt, ap );
+ va_end(ap);
+
+ if( buf ){
+ Jim_AppendString( interp, objPtr, buf, -1 );
+ jim_vasprintf_done(buf);
+ }
+}
+
+
void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr,
Jim_Obj *appendObjPtr)
{
* TODO: Lots of things work - via a hack
* However, no format item can be >= JIM_MAX_FMT
*/
-Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
- int objc, Jim_Obj *const *objv)
+#define JIM_MAX_FMT 2048
+static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
+ int objc, Jim_Obj *const *objv, char *sprintf_buf)
{
const char *fmt, *_fmt;
int fmtLen;
jim_wide wideValue;
double doubleValue;
/* we cheat and use Sprintf()! */
-#define JIM_MAX_FMT 2048
- char sprintf_buf[JIM_MAX_FMT];
char fmt_str[100];
char *cp;
int width;
return resObjPtr;
}
+Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
+ int objc, Jim_Obj *const *objv)
+{
+ char *sprintf_buf=malloc(JIM_MAX_FMT);
+ Jim_Obj *t=Jim_FormatString_Inner(interp, fmtObjPtr, objc, objv, sprintf_buf);
+ free(sprintf_buf);
+ return t;
+}
+
/* -----------------------------------------------------------------------------
* Compared String Object
* ---------------------------------------------------------------------------*/
return retcode;
}
-int Jim_Eval(Jim_Interp *interp, const char *script)
+int Jim_Eval_Named(Jim_Interp *interp, const char *script, const char *filename, int lineno)
{
- Jim_Obj *scriptObjPtr = Jim_NewStringObj(interp, script, -1);
int retval;
+ Jim_Obj *scriptObjPtr;
+ scriptObjPtr = Jim_NewStringObj(interp, script, -1);
Jim_IncrRefCount(scriptObjPtr);
+
+
+ if( filename ){
+ JimSetSourceInfo( interp, scriptObjPtr, filename, lineno );
+ }
+
retval = Jim_EvalObj(interp, scriptObjPtr);
Jim_DecrRefCount(interp, scriptObjPtr);
return retval;
}
+int Jim_Eval(Jim_Interp *interp, const char *script)
+{
+ return Jim_Eval_Named( interp, script, NULL, 0 );
+}
+
+
+
/* Execute script in the scope of the global level */
int Jim_EvalGlobal(Jim_Interp *interp, const char *script)
{
int nread, totread, maxlen, buflen;
int retval;
Jim_Obj *scriptObjPtr;
- char cwd[ 2048 ];
if ((fp = fopen(filename, "r")) == NULL) {
+ const int cwd_len=2048;
+ char *cwd=malloc(cwd_len);
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- getcwd( cwd, sizeof(cwd) );
+ getcwd( cwd, cwd_len );
Jim_AppendStrings(interp, Jim_GetResult(interp),
"Error loading script \"", filename, "\"",
" cwd: ", cwd,
" err: ", strerror(errno), NULL);
+ free(cwd);
return JIM_ERR;
}
buflen = 1024;
JIM_REGISTER_API(Alloc);
JIM_REGISTER_API(Free);
JIM_REGISTER_API(Eval);
+ JIM_REGISTER_API(Eval_Named);
JIM_REGISTER_API(EvalGlobal);
JIM_REGISTER_API(EvalFile);
JIM_REGISTER_API(EvalObj);
JIM_REGISTER_API(NewStringObj);
JIM_REGISTER_API(NewStringObjNoAlloc);
JIM_REGISTER_API(AppendString);
+ JIM_REGISTER_API(AppendString_sprintf);
JIM_REGISTER_API(AppendObj);
JIM_REGISTER_API(AppendStrings);
JIM_REGISTER_API(StringEqObj);
return JIM_OK;
}
+
+static void
+jim_get_s_us( jim_wide *s, jim_wide *us )
+{
+#if defined(WIN32)
+ /*
+ * Sorry - I do not have, or use Win32.
+ * This concept is from
+ *
+ * Method is from:
+ * http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/
+ *
+ * I have no method to test/verify.
+ * - Duane 6-sep-2008.
+ * (once verified, please somebody remove this comment)
+ */
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+#else
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif
+
+ FILETIME ft;
+ unsigned __int64 tmpres;
+ tmpres = 0;
+ GetSystemTimeAsFileTime( &ft );
+
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+ /* convert to unix representation */
+ tmpres /= 10;
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+
+ *s = (tmpres / 1000000ULL);
+ *us = (tmpres % 1000000ULL);
+
+#undef DELTA_EPOCH_IN_MICROSECS
+
+#else
+ /* LINUX/CYGWIN */
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday( &tv, &tz );
+ *s = tv.tv_sec;
+ *us = tv.tv_usec;
+#endif
+}
+
+
+/* [clock] */
+static int Jim_ClockCoreCommand( Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ /*
+ * See: TCL man page for 'clock'
+ * we do not impliment all features.
+ */
+ jim_wide r,s,us;
+ int option;
+ const char *options[] = {
+ "clicks",
+ "microseconds",
+ "milliseconds",
+ "seconds",
+ NULL
+ };
+ enum { OPT_CLICKS, OPT_USEC, OPT_MSEC, OPT_SEC };
+
+ if( argc < 2 ){
+ Jim_WrongNumArgs( interp, 1, argv, "option ?arguments ...?");
+ return JIM_ERR;
+ }
+
+ if( Jim_GetEnum(interp, argv[1], options, &option, "option",
+ JIM_ERRMSG) != JIM_OK ){
+ return JIM_ERR;
+ }
+
+ // platform independent get time.
+ jim_get_s_us( &s, &us );
+
+ r = 0;
+ switch(option){
+ case OPT_CLICKS:
+ case OPT_USEC:
+ /* clicks & usecs are the same */
+ r = (s * 1000000) + us;
+ break;
+ case OPT_MSEC:
+ r = (s * 1000) + (us / 1000);
+ break;
+ case OPT_SEC:
+ r = s;
+ break;
+ }
+
+ Jim_SetResult( interp, Jim_NewWideObj( interp, r ) );
+ return JIM_OK;
+}
+
+
static struct {
const char *name;
Jim_CmdProc cmdProc;
{"rand", Jim_RandCoreCommand},
{"package", Jim_PackageCoreCommand},
{"tailcall", Jim_TailcallCoreCommand},
+ {"clock", Jim_ClockCoreCommand},
{NULL, NULL},
};
Jim_Obj *o;
o = NULL; // failure
- if( goi->argc ){
+ if( goi->argc > 0 ){
// success
o = goi->argv[0];
goi->argc -= 1;
Jim_SetResult_sprintf( Jim_Interp *interp, const char *fmt,... )
{
va_list ap;
-#if 0
- /* yucky way */
- char buf[2048];
-
- va_start(ap,fmt);
- vsnprintf( buf, sizeof(buf), fmt, ap );
- va_end(ap);
- /* garentee termination */
- buf[2047] = 0;
- Jim_SetResultString( interp, buf, -1 );
-
-#else
char *buf;
+
va_start(ap,fmt);
- vasprintf( &buf, fmt, ap );
+ buf = jim_vasprintf( fmt, ap );
va_end(ap);
if( buf ){
Jim_SetResultString( interp, buf, -1 );
- free(buf);
+ jim_vasprintf_done(buf);
}
-#endif
return JIM_OK;
}