static status_t command_loop(int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked) { bool exit; #if WITH_LIB_ENV bool report_result; #endif cmd_args *args = NULL; const char *buffer; const char *continuebuffer; char *outbuf = NULL; args = (cmd_args *) malloc (MAX_NUM_ARGS * sizeof(cmd_args)); if (unlikely(args == NULL)) { goto no_mem_error; } const size_t outbuflen = 1024; outbuf = malloc(outbuflen); if (unlikely(outbuf == NULL)) { goto no_mem_error; } exit = false; continuebuffer = NULL; while (!exit) { // read a new line if it hadn't been split previously and passed back from tokenize_command if (continuebuffer == NULL) { if (showprompt) fputs("] ", stdout); int len = get_line(&buffer, get_line_cookie); if (len < 0) break; if (len == 0) continue; } else { buffer = continuebuffer; } // dprintf("line = '%s'\n", buffer); /* tokenize the line */ int argc = tokenize_command(buffer, &continuebuffer, outbuf, outbuflen, args, MAX_NUM_ARGS); if (argc < 0) { if (showprompt) printf("syntax error\n"); continue; } else if (argc == 0) { continue; } // dprintf("after tokenize: argc %d\n", argc); // for (int i = 0; i < argc; i++) // dprintf("%d: '%s'\n", i, args[i].str); /* convert the args */ convert_args(argc, args); /* try to match the command */ const cmd *command = match_command(args[0].str, CMD_AVAIL_NORMAL); if (!command) { if (showprompt) printf("command not found\n"); continue; } if (!locked) mutex_acquire(command_lock); abort_script = false; lastresult = command->cmd_callback(argc, args); #if WITH_LIB_ENV bool report_result; env_get_bool("reportresult", &report_result, false); if (report_result) { if (lastresult < 0) printf("FAIL %d\n", lastresult); else printf("PASS %d\n", lastresult); } #endif #if WITH_LIB_ENV // stuff the result in an environment var env_set_int("?", lastresult, true); #endif // someone must have aborted the current script if (abort_script) exit = true; abort_script = false; if (!locked) mutex_release(command_lock); } free(outbuf); free(args); return NO_ERROR; no_mem_error: if (outbuf) free(outbuf); if (args) free(args); dprintf(INFO, "%s: not enough memory\n", __func__); return ERR_NO_MEMORY; }
static void command_loop(int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked) { bool exit; bool report_result; cmd_args args[16]; const char *buffer; const char *continuebuffer; char *outbuf; const size_t outbuflen = 1024; outbuf = malloc(outbuflen); exit = false; continuebuffer = NULL; while (!exit) { // read a new line if it hadn't been split previously and passed back from tokenize_command if (continuebuffer == NULL) { if (showprompt) puts("] "); int len = get_line(&buffer, get_line_cookie); if (len < 0) break; if (len == 0) continue; } else { buffer = continuebuffer; } // dprintf("line = '%s'\n", buffer); /* tokenize the line */ int argc = tokenize_command(buffer, &continuebuffer, outbuf, outbuflen, args, 16); if (argc < 0) { if (showprompt) printf("syntax error\n"); continue; } else if (argc == 0) { continue; } // dprintf("after tokenize: argc %d\n", argc); // for (int i = 0; i < argc; i++) // dprintf("%d: '%s'\n", i, args[i].str); /* convert the args */ convert_args(argc, args); /* try to match the command */ const cmd *command = match_command(args[0].str); if (!command) { if (showprompt) printf("command not found\n"); continue; } if (!locked) mutex_acquire(command_lock); abort_script = false; lastresult = command->cmd_callback(argc, args); #if WITH_LIB_ENV if ((env_get_bool("reportresult", &report_result, false) >= 0) && (report_result)) { if (lastresult < 0) printf("FAIL %d\n", lastresult); else printf("PASS %d\n", lastresult); } #endif #if WITH_LIB_ENV // stuff the result in an environment var env_set_int("?", lastresult, true); #endif // someone must have aborted the current script if (abort_script) exit = true; abort_script = false; if (!locked) mutex_release(command_lock); } free(outbuf); }