- /* init state correctly */
- if (*state == -1)
- *state = 0;
-
- debug_printf("Multiple choice STATE=%d\n", *state);
-
- inst_num = 0;
- inst = ctx[inst_num];
- while (inst) {
- /* we need to redo it */
- inst = ctx[inst_num];
-
- if (nb_token && match_inst(inst, buf, nb_token, NULL))
- goto next2;
-
- token_p = inst->tokens[nb_token];
- if (token_p)
- memcpy(&token_hdr, token_p, sizeof(token_hdr));
-
- /* one choice for this token */
- if (!token_p ||
- !token_hdr.ops->complete_get_nb ||
- !token_hdr.ops->complete_get_elt ||
- (n = token_hdr.ops->complete_get_nb(token_p)) == 0) {
- if (local_state < *state) {
- local_state++;
- goto next2;
- }
- (*state)++;
- if (token_p && token_hdr.ops->get_help) {
- token_hdr.ops->get_help(token_p, tmpbuf, sizeof(tmpbuf));
- help_str = inst->help_str;
- if (help_str)
- snprintf(dst, size, "[%s]: %s", tmpbuf, help_str);
- else
- snprintf(dst, size, "[%s]: No help", tmpbuf);
- }
- else {
- snprintf(dst, size, "[RETURN]");
- }
- return 1;
+ return 0;
+}
+
+/* try to complete the buffer given as a parameter */
+int
+cmdline_complete(cmdline_parse_ctx_t *ctx, const char *buf,
+ char *dst, unsigned int dstsize)
+{
+ cmdline_parse_token_hdr_t *token;
+ cmdline_parse_inst_t **pinst;
+ cmdline_parse_inst_t *inst;
+ struct cmdline_preparse preparse;
+ int nb_match = 0;
+ int nb_completion = 0;
+ int completion_len = CMDLINE_MAX_TOKEN_SIZE;
+ char completion_buf[CMDLINE_MAX_TOKEN_SIZE];
+ char tmpbuf[CMDLINE_MAX_TOKEN_SIZE];
+ int ret, n;
+
+ debug_printf("%s called\n", __FUNCTION__);
+
+ /* fill the preparse structure that contains infos that will
+ * help us to complete the buffer */
+ ret = cmdline_preparse(&preparse, buf);
+ if (ret < 0)
+ return CMDLINE_COMPLETE_NONE;
+
+ /* try to complete !! */
+ for (pinst = &ctx->insts[0]; *pinst != NULL; pinst++) {
+ inst = *pinst;
+
+ debug_printf("INST\n");
+
+ /* try to match the first tokens */
+ if (preparse.nb_valid_tok != 0 &&
+ match_inst(inst, buf, preparse.nb_valid_tok,
+ NULL, 0) != 0)
+ continue;
+
+ nb_match ++;
+ token = inst->tokens[preparse.nb_valid_tok];
+
+ /* non completable */
+ if (token == NULL ||
+ token->ops->complete_start == NULL ||
+ token->ops->complete_iterate == NULL)
+ continue;
+
+ /* store the incomplete token in tmpbuf */
+ n = preparse.comp_tok_len + 1;
+ if (n > sizeof(tmpbuf))
+ n = sizeof(tmpbuf);
+ snprintf(tmpbuf, n, "%s", preparse.comp_tok_buf);
+
+ /* non completable */
+ if (token->ops->complete_start(token, tmpbuf,
+ &preparse.opaque) < 0) {
+ if (token->ops->complete_end != NULL)
+ token->ops->complete_end(token,
+ &preparse.opaque);
+ continue;