duane ellis: (A) a new concept called "Name Value Pair" or NVP, in simple terms: Think: "String" and "Value". There can be many strings - all related to a single value, for examle: "T", "t", "y", "1", "yes", all can represent "truth", the reverse mapping is more simplistic - the first matching number wins.
(B) a new "getopt" like feature for Jim - that simplifies argument parsing in complex functions, normally this would be used in conjunction with either an NVP table of options, or a more simpler Enumeration table. In contrast to the GNU "getopt" package, this is more of a "object model or code oriented" solution then a pure data structure used by GNU getopt, or the main stream Tcl/Tk option processing. git-svn-id: svn://svn.berlios.de/openocd/trunk@936 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
459
src/helper/jim.c
459
src/helper/jim.c
@@ -2510,9 +2510,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 +2547,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
|
||||
*
|
||||
@@ -9151,6 +9174,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);
|
||||
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
@@ -12162,3 +12216,404 @@ 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 ){
|
||||
// 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;
|
||||
#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 );
|
||||
va_end(ap);
|
||||
if( buf ){
|
||||
Jim_SetResultString( interp, buf, -1 );
|
||||
free(buf);
|
||||
}
|
||||
#endif
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables: ***
|
||||
* c-basic-offset: 4 ***
|
||||
* tab-width: 4 ***
|
||||
* End: ***
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user