+ len = strlen(text);
+ while (*ptr)
+ {
+ if ( (len < strlen(ptr)) &&
+ !strncmp(text, ptr, len) )
+ return strdup(ptr);
+
+ ptr += strlen(ptr)+1;
+ }
+
+ return NULL;
+}
+
+// readline library completion function.
+// completes from the list of all sdcdb command.
+char *completionCommandsList(const char *text, int state)
+{
+ static int i = 0;
+
+ if (state == 0) // new completion?
+ { // yes, only complete if this is the first token on the line.
+ int ok = 0; // try to complete this request?
+ char *p = rl_line_buffer;
+
+ // skip blanks
+ while (p && isspace(*p))
+ {
+ if (p-rl_line_buffer == rl_point)
+ ok = 1;
+ p++;
+ }
+
+ while (p && !isspace(*p))
+ {
+ if (p-rl_line_buffer == rl_point)
+ ok = 1;
+ p++;
+ }
+
+ if (p-rl_line_buffer == rl_point)
+ ok = 1;
+
+ if ( !ok )
+ return NULL; // no more completions
+
+ i = 0; // ok, gonna complete. initialize static variable.
+ }
+ else i++;
+
+ for (; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++)
+ {
+ int len = strlen(text);
+ if (len <= strlen(cmdTab[i].cmd))
+ {
+ if (strncmp(text,cmdTab[i].cmd,len) == 0)
+ return strdup(cmdTab[i].cmd);
+ }
+ }
+
+ return NULL; // no more completions
+}
+
+// readline library completion function.
+// completes from the list of symbols.
+char *completionSymbolName(const char *text, int state)
+{
+ static symbol *sy;
+
+ if (state == 0) // new completion?
+ sy = setFirstItem(symbols); // yes
+ else
+ sy = setNextItem(symbols);
+
+ for (; sy != NULL; )
+ {
+ int len = strlen(text);
+ if (len <= strlen(sy->name))
+ {
+ if (strncmp(text,sy->name,len) == 0)
+ return strdup(sy->name);
+ }
+
+ sy = setNextItem(symbols);
+ }
+ return NULL;
+}
+
+// readline library completion function.
+// completes from the list known functions.
+// module_flag - if false, ignore function module name
+// if true, compare against module_name:fnction_name
+char *completionFunctionName(const char *text, int state, int module_flag)
+{
+ static function *f;
+
+ if (state == 0) // new completion?
+ f = setFirstItem(functions); // yes
+ else
+ f = setNextItem(functions);
+
+ for (; f != NULL; )
+ {
+ int text_len = strlen(text);
+
+ if (!module_flag)
+ {
+ if (text_len <= strlen(f->sym->name) &&
+ !strncmp(text,f->sym->name,text_len))
+ return strdup(f->sym->name);
+ }
+ else
+ {
+ int modname_len = strlen(f->mod->c_name);
+ int funcname_len = strlen(f->sym->name);
+ char *functext = malloc(modname_len+funcname_len+2);
+ //assert(functext);
+ strcpy(functext,f->mod->c_name);
+ strcat(functext,":");
+ strcat(functext,f->sym->name);
+ if (text_len <= strlen(functext) &&
+ !strncmp(text,functext,text_len))
+ return functext;
+ else
+ free(functext);
+ }
+ f = setNextItem(functions);
+ }
+ return NULL;
+}
+
+// readline library completion function.
+// completes from the list known modules.
+char *completionModuleName(const char *text, int state)
+{
+ static module *m;
+
+ if (state == 0) // new completion?
+ m = setFirstItem(modules); // yes
+ else
+ m = setNextItem(modules);
+
+ for (; m != NULL; )
+ {
+ int len = strlen(text);
+ if ( (len <= strlen(m->c_name)) &&
+ !strncmp(text,m->c_name,len) )
+ return strdup(m->c_name);
+
+ if ( (len <= strlen(m->asm_name)) &&
+ (strncmp(text,m->asm_name,len) == 0) )
+ return strdup(m->asm_name);
+
+ m = setNextItem(modules);
+ }
+ return NULL;
+}
+
+// readline completion function for "file" command
+char *completionCmdFile(const char *text, int state)
+{
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ }
+
+ // we use filename_completion_function() from the readline library.
+ return rl_filename_completion_function(text, state);
+}
+
+// readline completion function for "source" command
+char *completionCmdSource(const char *text, int state)
+{
+ return completionCmdFile(text, state);
+}
+
+// readline completion function for "info" command
+char *completionCmdInfo(const char *text, int state)
+{
+ static char *ptr;
+
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ }
+
+ return completionCompleteFromStrList(text, state,
+ "break\0stack\0frame\0registers\0all-registers\0"
+ "line\0source\0functions\0symbols\0variables\0");
+}
+
+// readline completion function for "show" command
+char *completionCmdShow(const char *text, int state)
+{
+ static char *ptr;
+
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ }
+ return completionCompleteFromStrList(text, state, "copying\0warranty\0");
+}
+
+// readline completion function for "la" command
+char *completionCmdListSymbols(const char *text, int state)
+{
+ static char *ptr;
+
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ }
+ return completionCompleteFromStrList(text, state, "v1\0v2\0");
+}
+
+char *completionCmdPrintType(const char *text, int state)
+{
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ }
+ return completionSymbolName(text, state);
+}
+
+char *completionCmdPrint(const char *text, int state)
+{
+ if (state == 0)
+ {
+ int i = completionHelper_GetCurrTokenNumber();
+ if (i != 1 && i != 2)
+ return NULL;
+ }
+ return completionSymbolName(text, state);
+}
+
+char *completionCmdDelUserBp(const char *text, int state)
+{
+ static breakp *bp;
+ static int k;
+
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+
+ if (!userBpPresent)
+ return NULL;
+
+ bp = hTabFirstItem(bptable,&k);
+ }
+ else
+ bp = hTabNextItem(bptable,&k);
+
+ for ( ; bp ; bp = hTabNextItem(bptable,&k))
+ {
+ if (bp->bpType == USER || bp->bpType == TMPUSER)
+ {
+ char buff[20];
+ sprintf(buff, "%d", bp->bpnum);
+ return strdup(buff);
+ }
+ }
+
+ return NULL;
+}
+
+// readline completion function for "undisplay" command
+char *completionCmdUnDisplay(const char *text, int state)
+{
+ static dsymbol *dsym;
+
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+ dsym = setFirstItem(dispsymbols);
+ }
+
+ if (dsym)
+ {
+ char buff[30];
+ sprintf(buff, "%d", dsym->dnum);
+ dsym = setNextItem(dispsymbols);
+ return strdup(buff);
+ }
+ return NULL;
+}
+
+char *completionCmdSetUserBp(const char *text, int state)
+{
+ static int internal_state; // 0=calling completionFunctionName(text, state, 0)
+ // 1=calling completionFunctionName(text, 1, 1)
+ if (state == 0)
+ {
+ if (completionHelper_GetCurrTokenNumber() != 1)
+ return NULL;
+
+ internal_state = 0;
+ }
+ if (internal_state == 0)
+ {
+ char *p = completionFunctionName(text, state, 0);
+ if (p)
+ return p;
+ internal_state = 1;
+ return completionFunctionName(text, 0, 1);
+ }
+ else
+ {
+ return completionFunctionName(text, 1, 1);
+ }
+}
+
+char *completionCmdSetOption(const char *text, int state)
+{
+ static char *ptr;
+ static int currtok;
+
+ if (state == 0)
+ {
+ int start,end;
+
+ currtok = completionHelper_GetCurrTokenNumber();
+
+ if (currtok == 2 || currtok == 3)
+ {
+ // make sure token 1 == "variable"
+ completionHelper_GetTokenNumber(1, &start, &end);
+ if (end - start != 8 ||
+ strncmp(rl_line_buffer+start,"variable",8))
+ return NULL;
+ }
+ else if (currtok != 1)
+ {
+ return NULL;
+ }
+ }
+
+ switch (currtok)
+ {
+ case 1:
+ return completionCompleteFromStrList(text, state,
+#ifdef SDCDB_DEBUG
+ "debug\0"
+#endif
+ "srcmode\0listsize\0variable\0");
+ case 2:
+ return completionSymbolName(text, state);
+
+ case 3:
+ return completionCompleteFromStrList(text, state, "=\0");
+ }
+}
+
+// our main readline completion function
+// calls the other completion functions as needed.
+char *completionMain(const char *text, int state)
+{
+ static rl_compentry_func_t *compl_func;
+ int i, start, end, len;
+
+ if (state == 0) // new completion?
+ {
+ compl_func = NULL;