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:
oharboe
2008-08-19 11:49:48 +00:00
parent 5227c98f3f
commit bbe7110f42
2 changed files with 792 additions and 4 deletions

View File

@@ -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: ***
*/