X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fhelper%2Fjim.c;h=75e7e6cb656f0468c7fe967252fcdb781fbe76f6;hb=68c598e88d5e09728ea845a81ab279c615bbaf0f;hp=1a35b32b053422ff0091322b915e24496c09e3ea;hpb=ce16ff901c63c65d6087af4436159a6529de3b95;p=openocd.git diff --git a/src/helper/jim.c b/src/helper/jim.c index 1a35b32b05..75e7e6cb65 100644 --- a/src/helper/jim.c +++ b/src/helper/jim.c @@ -57,6 +57,11 @@ #include #include #include +#if defined(WIN32) +/* sys/time - need is different */ +#else +#include // for gettimeofday() +#endif #include "replacements.h" @@ -111,6 +116,33 @@ static Jim_HashTableType JimVariablesHashTableType; * 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. @@ -2019,6 +2051,22 @@ void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str, 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) { @@ -2173,8 +2221,9 @@ static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) * 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; @@ -2190,8 +2239,6 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, 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; @@ -2456,6 +2503,15 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, 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 * ---------------------------------------------------------------------------*/ @@ -2510,9 +2566,9 @@ int qsortCompareStringPointers(const void *a, const void *b) } int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, - const char **tablePtr, int *indexPtr, const char *name, int flags) + const char * const *tablePtr, int *indexPtr, const char *name, int flags) { - const char **entryPtr = NULL; + const char * const *entryPtr = NULL; char **tablePtrSorted; int i, count = 0; @@ -2547,6 +2603,29 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, return JIM_ERR; } +int Jim_GetNvp(Jim_Interp *interp, + Jim_Obj *objPtr, + const Jim_Nvp *nvp_table, + const Jim_Nvp ** result) +{ + Jim_Nvp *n; + int e; + + e = Jim_Nvp_name2value_obj( interp, nvp_table, objPtr, &n ); + if( e == JIM_ERR ){ + return e; + } + + /* Success? found? */ + if( n->name ){ + /* remove const */ + *result = (Jim_Nvp *)n; + return JIM_OK; + } else { + return JIM_ERR; + } +} + /* ----------------------------------------------------------------------------- * Source Object * @@ -8695,17 +8774,31 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, 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) { @@ -8754,15 +8847,17 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename) 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; @@ -9043,6 +9138,7 @@ void JimRegisterCoreApi(Jim_Interp *interp) 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); @@ -9069,6 +9165,7 @@ void JimRegisterCoreApi(Jim_Interp *interp) 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); @@ -9151,6 +9248,37 @@ void JimRegisterCoreApi(Jim_Interp *interp) JIM_REGISTER_API(StackPop); JIM_REGISTER_API(StackPeek); JIM_REGISTER_API(FreeStackElements); + JIM_REGISTER_API(fprintf ); + JIM_REGISTER_API(vfprintf ); + JIM_REGISTER_API(fwrite ); + JIM_REGISTER_API(fread ); + JIM_REGISTER_API(fflush ); + JIM_REGISTER_API(fgets ); + JIM_REGISTER_API(GetNvp); + JIM_REGISTER_API(Nvp_name2value); + JIM_REGISTER_API(Nvp_name2value_simple); + JIM_REGISTER_API(Nvp_name2value_obj); + JIM_REGISTER_API(Nvp_name2value_nocase); + JIM_REGISTER_API(Nvp_name2value_obj_nocase); + + JIM_REGISTER_API(Nvp_value2name); + JIM_REGISTER_API(Nvp_value2name_simple); + JIM_REGISTER_API(Nvp_value2name_obj); + + JIM_REGISTER_API(GetOpt_Setup); + JIM_REGISTER_API(GetOpt_Debug); + JIM_REGISTER_API(GetOpt_Obj); + JIM_REGISTER_API(GetOpt_String); + JIM_REGISTER_API(GetOpt_Double); + JIM_REGISTER_API(GetOpt_Wide); + JIM_REGISTER_API(GetOpt_Nvp); + JIM_REGISTER_API(GetOpt_NvpUnknown); + JIM_REGISTER_API(GetOpt_Enum); + + JIM_REGISTER_API(Debug_ArgvString); + JIM_REGISTER_API(SetResult_sprintf); + JIM_REGISTER_API(SetResult_NvpUnknown); + } /* ----------------------------------------------------------------------------- @@ -11916,6 +12044,108 @@ static int Jim_PackageCoreCommand(Jim_Interp *interp, int argc, 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; @@ -11980,6 +12210,7 @@ static struct { {"rand", Jim_RandCoreCommand}, {"package", Jim_PackageCoreCommand}, {"tailcall", Jim_TailcallCoreCommand}, + {"clock", Jim_ClockCoreCommand}, {NULL, NULL}, }; @@ -12162,3 +12393,383 @@ char* Jim_fgets( Jim_Interp *interp, char *s, int size, void *cookie ) } return (*(interp->cb_fgets))( s, size, cookie ); } + +Jim_Nvp * +Jim_Nvp_name2value_simple( const Jim_Nvp *p, const char *name ) +{ + while( p->name ){ + if( 0 == strcmp( name, p->name ) ){ + break; + } + p++; + } + return ((Jim_Nvp *)(p)); +} + +Jim_Nvp * +Jim_Nvp_name2value_nocase_simple( const Jim_Nvp *p, const char *name ) +{ + while( p->name ){ + if( 0 == strcasecmp( name, p->name ) ){ + break; + } + p++; + } + return ((Jim_Nvp *)(p)); +} + +int +Jim_Nvp_name2value_obj( Jim_Interp *interp, + const Jim_Nvp *p, + Jim_Obj *o, + Jim_Nvp **result ) +{ + return Jim_Nvp_name2value( interp, p, Jim_GetString( o, NULL ), result ); +} + + +int +Jim_Nvp_name2value( Jim_Interp *interp, + const Jim_Nvp *_p, + const char *name, + Jim_Nvp **result) +{ + const Jim_Nvp *p; + + p = Jim_Nvp_name2value_simple( _p, name ); + + /* result */ + if( result ){ + *result = (Jim_Nvp *)(p); + } + + /* found? */ + if( p->name ){ + return JIM_OK; + } else { + return JIM_ERR; + } +} + +int +Jim_Nvp_name2value_obj_nocase( Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **puthere ) +{ + return Jim_Nvp_name2value_nocase( interp, p, Jim_GetString( o, NULL ), puthere ); +} + +int +Jim_Nvp_name2value_nocase( Jim_Interp *interp, const Jim_Nvp *_p, const char *name, Jim_Nvp **puthere ) +{ + const Jim_Nvp *p; + + p = Jim_Nvp_name2value_nocase_simple( _p, name ); + + if( puthere ){ + *puthere = (Jim_Nvp *)(p); + } + /* found */ + if( p->name ){ + return JIM_OK; + } else { + return JIM_ERR; + } +} + + +int +Jim_Nvp_value2name_obj( Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result ) +{ + int e;; + jim_wide w; + + e = Jim_GetWide( interp, o, &w ); + if( e != JIM_OK ){ + return e; + } + + return Jim_Nvp_value2name( interp, p, w, result ); +} + +Jim_Nvp * +Jim_Nvp_value2name_simple( const Jim_Nvp *p, int value ) +{ + while( p->name ){ + if( value == p->value ){ + break; + } + p++; + } + return ((Jim_Nvp *)(p)); +} + + +int +Jim_Nvp_value2name( Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp **result ) +{ + const Jim_Nvp *p; + + p = Jim_Nvp_value2name_simple( _p, value ); + + if( result ){ + *result = (Jim_Nvp *)(p); + } + + if( p->name ){ + return JIM_OK; + } else { + return JIM_ERR; + } +} + + +int +Jim_GetOpt_Setup( Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj * const * argv) +{ + memset( p, 0, sizeof(*p) ); + p->interp = interp; + p->argc = argc; + p->argv = argv; + + return JIM_OK; +} + +void +Jim_GetOpt_Debug( Jim_GetOptInfo *p ) +{ + int x; + + Jim_fprintf( p->interp, p->interp->cookie_stderr, "---args---\n"); + for( x = 0 ; x < p->argc ; x++ ){ + Jim_fprintf( p->interp, p->interp->cookie_stderr, + "%2d) %s\n", + x, + Jim_GetString( p->argv[x], NULL ) ); + } + Jim_fprintf( p->interp, p->interp->cookie_stderr, "-------\n"); +} + + +int +Jim_GetOpt_Obj( Jim_GetOptInfo *goi, Jim_Obj **puthere ) +{ + Jim_Obj *o; + + o = NULL; // failure + if( goi->argc > 0 ){ + // success + o = goi->argv[0]; + goi->argc -= 1; + goi->argv += 1; + } + if( puthere ){ + *puthere = o; + } + if( o != NULL ){ + return JIM_OK; + } else { + return JIM_ERR; + } +} + +int +Jim_GetOpt_String( Jim_GetOptInfo *goi, char **puthere, int *len ) +{ + int r; + Jim_Obj *o; + const char *cp; + + + r = Jim_GetOpt_Obj( goi, &o ); + if( r == JIM_OK ){ + cp = Jim_GetString( o, len ); + if( puthere ){ + /* remove const */ + *puthere = (char *)(cp); + } + } + return r; +} + +int +Jim_GetOpt_Double( Jim_GetOptInfo *goi, double *puthere ) +{ + int r; + Jim_Obj *o; + double _safe; + + if( puthere == NULL ){ + puthere = &_safe; + } + + r = Jim_GetOpt_Obj( goi, &o ); + if( r == JIM_OK ){ + r = Jim_GetDouble( goi->interp, o, puthere ); + if( r != JIM_OK ){ + Jim_SetResult_sprintf( goi->interp, + "not a number: %s", + Jim_GetString( o, NULL ) ); + } + } + return r; +} + +int +Jim_GetOpt_Wide( Jim_GetOptInfo *goi, jim_wide *puthere ) +{ + int r; + Jim_Obj *o; + jim_wide _safe; + + if( puthere == NULL ){ + puthere = &_safe; + } + + r = Jim_GetOpt_Obj( goi, &o ); + if( r == JIM_OK ){ + r = Jim_GetWide( goi->interp, o, puthere ); + } + return r; +} + +int Jim_GetOpt_Nvp( Jim_GetOptInfo *goi, + const Jim_Nvp *nvp, + Jim_Nvp **puthere) +{ + Jim_Nvp *_safe; + Jim_Obj *o; + int e; + + if( puthere == NULL ){ + puthere = &_safe; + } + + e = Jim_GetOpt_Obj( goi, &o ); + if( e == JIM_OK ){ + e = Jim_Nvp_name2value_obj( goi->interp, + nvp, + o, + puthere ); + } + + return e; +} + +void +Jim_GetOpt_NvpUnknown( Jim_GetOptInfo *goi, + const Jim_Nvp *nvptable, + int hadprefix ) +{ + if( hadprefix ){ + Jim_SetResult_NvpUnknown( goi->interp, + goi->argv[-2], + goi->argv[-1], + nvptable ); + } else { + Jim_SetResult_NvpUnknown( goi->interp, + NULL, + goi->argv[-1], + nvptable ); + } +} + + +int +Jim_GetOpt_Enum( Jim_GetOptInfo *goi, + const char * const * lookup, + int *puthere) +{ + int _safe; + Jim_Obj *o; + int e; + + if( puthere == NULL ){ + puthere = &_safe; + } + e = Jim_GetOpt_Obj( goi, &o ); + if( e == JIM_OK ){ + e = Jim_GetEnum( goi->interp, + o, + lookup, + puthere, + "option", + JIM_ERRMSG ); + } + return e; +} + + + +int +Jim_SetResult_sprintf( Jim_Interp *interp, const char *fmt,... ) +{ + va_list ap; + char *buf; + + va_start(ap,fmt); + buf = jim_vasprintf( fmt, ap ); + va_end(ap); + if( buf ){ + Jim_SetResultString( interp, buf, -1 ); + jim_vasprintf_done(buf); + } + return JIM_OK; +} + + +void +Jim_SetResult_NvpUnknown( Jim_Interp *interp, + Jim_Obj *param_name, + Jim_Obj *param_value, + const Jim_Nvp *nvp ) +{ + if( param_name ){ + Jim_SetResult_sprintf( interp, + "%s: Unknown: %s, try one of: ", + Jim_GetString( param_name, NULL ), + Jim_GetString( param_value, NULL ) ); + } else { + Jim_SetResult_sprintf( interp, + "Unknown param: %s, try one of: ", + Jim_GetString( param_value, NULL ) ); + } + while( nvp->name ){ + const char *a; + const char *b; + + if( (nvp+1)->name ){ + a = nvp->name; + b = ", "; + } else { + a = "or "; + b = nvp->name; + } + Jim_AppendStrings( interp, + Jim_GetResult(interp), + a, b, NULL ); + nvp++; + } +} + + +static Jim_Obj *debug_string_obj; + +const char * +Jim_Debug_ArgvString( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) +{ + int x; + + if( debug_string_obj ){ + Jim_FreeObj( interp, debug_string_obj ); + } + + debug_string_obj = Jim_NewEmptyStringObj( interp ); + for( x = 0 ; x < argc ; x++ ){ + Jim_AppendStrings( interp, + debug_string_obj, + Jim_GetString( argv[x], NULL ), + " ", + NULL ); + } + + return Jim_GetString( debug_string_obj, NULL ); +}