int _which_one(QSP_ARG_DECL const char *prompt, int n, const char** choices) { int i; int nmatches=0; int lastmatch=(-1); /* init to elim warning */ const char *user_response; #ifdef HAVE_HISTORY check_preload(prompt, n, choices); #endif /* HAVE_HISTORY */ user_response = nameof(prompt); for(i=0;i<n;i++){ assert(choices[i]!=NULL); if( !strcmp( user_response, choices[i] ) ){ return(i); } } /* if no exact match check for substring match */ for(i=0;i<n;i++) if( is_a_substring( user_response, choices[i] ) ){ lastmatch=i; nmatches++; } if( nmatches==1 ){ sprintf(ERROR_STRING,"Unambiguous substring match of \"%s\" to \"%s\"", user_response,choices[lastmatch]); //advise(ERROR_STRING); warn(ERROR_STRING); return(lastmatch); } else if( nmatches > 1 ){ sprintf(ERROR_STRING,"ambiguous choice \"%s\"",user_response); warn(ERROR_STRING); return(-1); } sprintf(ERROR_STRING,"invalid choice \"%s\"",user_response); warn(ERROR_STRING); sprintf(ERROR_STRING,"valid selections for %s are:",prompt); advise(ERROR_STRING); for(i=0;i<n;i++){ sprintf(ERROR_STRING,"\t%s",choices[i]); advise(ERROR_STRING); } #ifdef HAVE_HISTORY if( intractive() ) rem_def(prompt,user_response) ; #endif /* HAVE_HISTORY */ return(-1); }
static void _check_preload(QSP_ARG_DECL const char *prompt, int n, const char **choices) { const char *pline; if( ! IS_COMPLETING(THIS_QSP) ) return; if( ! intractive() ) return; if( *prompt == 0 ) return; // Need to format the prompt! pline = format_prompt(PROMPT_FORMAT, prompt); preload_history_list(pline,n,choices); }
Data_Obj *_pick_obj(QSP_ARG_DECL const char *pmpt) { const char *s; if( pmpt==NULL || *pmpt==0 ) pmpt="data object"; /* default prompt */ #ifdef HAVE_HISTORY /* pick_item() won't accept names with appended subscripts; * therefore use nameof and initialize the choices manually */ /* We might accidentally call this before dataobj_init()... */ if( dobj_itp == NULL ) dataobj_init(); // probably unnecessary now that we // call this when initializing a query stack... // That was done to get number formatting, // but probably that should be pulled out of data objects... if( intractive() ) init_item_hist(dobj_itp,pmpt); #endif /* HAVE_HISTORY */ s=NAMEOF(pmpt); return( get_obj(s) ); }
static COMMAND_FUNC( do_chng_one ) { Param *p; const char **pnlist; int nlist=0; int i=0; const char *s; p=theptbl; /* count the number of parameters */ while( p->p_type != NULL_P_TYPE ) { nlist++; p++; } pnlist = (const char **) getbuf( (nlist+1) * sizeof(char *) ); if( pnlist == NULL ) mem_err("do_chng_one"); #ifdef HAVE_HISTORY if( intractive(SINGLE_QSP_ARG) && IS_TRACKING_HISTORY(THIS_QSP) ){ List *lp; Node *np; lp = new_list(); for(i=0;i<nlist;i++){ pnlist[i] = theptbl[i].p_name; np = mk_node(&theptbl[i]); addTail(lp,np); } pnlist[i]="all"; np = mk_node(&pnlist[i]); addTail(lp,np); if( intractive(SINGLE_QSP_ARG) ){ char pline[LLEN]; make_prompt(QSP_ARG pline,PNAME_PMPT); new_defs(QSP_ARG pline); /* is this needed? */ init_hist_from_item_list(QSP_ARG PNAME_PMPT,lp); } dellist(lp); } #else /* ! HAVE_HISTORY */ for(i=0;i<nlist;i++) pnlist[i] = theptbl[i].p_name; #endif /* ! HAVE_HISTORY */ s=NAMEOF(PNAME_PMPT); if( !strcmp(s,"all") ){ p=theptbl; while( p->p_type != NULL_P_TYPE ) { getparm(QSP_ARG p); showparm(QSP_ARG p); p++; } return; } else if( get_pval(QSP_ARG s,theptbl) == -1 ){ sprintf(ERROR_STRING,"Unknown parameter \"%s\"",s); WARN(ERROR_STRING); } }