Changeset 4728 for pjproject/trunk/pjlib-util/src/pjlib-util/cli_console.c
- Timestamp:
- Feb 4, 2014 10:13:56 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/src/pjlib-util/cli_console.c
r4537 r4728 46 46 pj_thread_t *input_thread; 47 47 pj_bool_t thread_quit; 48 pj_sem_t *thread_sem; 49 pj_cli_console_cfg cfg; 48 pj_sem_t *thread_sem; 49 pj_cli_console_cfg cfg; 50 50 51 51 struct async_input_t 52 { 52 { 53 53 char *buf; 54 unsigned maxlen; 54 unsigned maxlen; 55 55 pj_sem_t *sem; 56 56 } input; … … 127 127 if (!pool) 128 128 return PJ_ENOMEM; 129 129 130 130 sess = PJ_POOL_ZALLOC_T(pool, pj_cli_sess); 131 131 fe = PJ_POOL_ZALLOC_T(pool, struct cli_console_fe); … … 136 136 } 137 137 sess->fe = &fe->base; 138 sess->log_level = param->log_level; 138 sess->log_level = param->log_level; 139 139 sess->op = PJ_POOL_ZALLOC_T(pool, struct pj_cli_sess_op); 140 140 fe->base.op = PJ_POOL_ZALLOC_T(pool, struct pj_cli_front_end_op); … … 155 155 156 156 pj_cli_register_front_end(cli, &fe->base); 157 if (param->prompt_str.slen == 0) { 157 if (param->prompt_str.slen == 0) { 158 158 pj_str_t prompt_sign = pj_str(">>> "); 159 159 fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool, prompt_sign.slen+1); 160 pj_strcpy(&fe->cfg.prompt_str, &prompt_sign); 160 pj_strcpy(&fe->cfg.prompt_str, &prompt_sign); 161 161 } else { 162 fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool, 162 fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool, 163 163 param->prompt_str.slen+1); 164 164 pj_strcpy(&fe->cfg.prompt_str, ¶m->prompt_str); 165 } 166 fe->cfg.prompt_str.ptr[fe->cfg.prompt_str.slen] = 0; 165 } 166 fe->cfg.prompt_str.ptr[fe->cfg.prompt_str.slen] = 0; 167 167 168 168 if (param->quit_command.slen) … … 184 184 send_data.ptr = data_str; 185 185 send_data.slen = 0; 186 186 187 187 pj_strcat(&send_data, &fe->cfg.prompt_str); 188 188 send_data.ptr[send_data.slen] = 0; … … 191 191 } 192 192 193 static void send_err_arg(pj_cli_sess *sess, 194 const pj_cli_exec_info *info, 193 static void send_err_arg(pj_cli_sess *sess, 194 const pj_cli_exec_info *info, 195 195 const pj_str_t *msg, 196 196 pj_bool_t with_return) … … 219 219 220 220 send_data.ptr[send_data.slen] = 0; 221 printf("%s", send_data.ptr); 222 } 223 224 static void send_inv_arg(pj_cli_sess *sess, 221 printf("%s", send_data.ptr); 222 } 223 224 static void send_inv_arg(pj_cli_sess *sess, 225 225 const pj_cli_exec_info *info, 226 226 pj_bool_t with_return) … … 230 230 } 231 231 232 static void send_too_many_arg(pj_cli_sess *sess, 232 static void send_too_many_arg(pj_cli_sess *sess, 233 233 const pj_cli_exec_info *info, 234 234 pj_bool_t with_return) … … 238 238 } 239 239 240 static void send_hint_arg(pj_str_t *send_data, 240 static void send_hint_arg(pj_str_t *send_data, 241 241 const pj_str_t *desc, 242 242 pj_ssize_t cmd_len, … … 257 257 } 258 258 259 static void send_ambi_arg(pj_cli_sess *sess, 259 static void send_ambi_arg(pj_cli_sess *sess, 260 260 const pj_cli_exec_info *info, 261 261 pj_bool_t with_return) … … 270 270 pj_ssize_t max_length = 0; 271 271 pj_ssize_t cmd_length = 0; 272 const pj_str_t *cmd_desc = 0;273 272 static const pj_str_t sc_type = {"sc", 2}; 274 273 static const pj_str_t choice_type = {"choice", 6}; 275 274 send_data.ptr = data; 276 275 send_data.slen = 0; 277 276 278 277 if (with_return) 279 278 pj_strcat2(&send_data, "\r\n"); … … 284 283 pj_strcat2(&send_data, " "); 285 284 } 286 pj_strcat2(&send_data, "^"); 285 pj_strcat2(&send_data, "^"); 287 286 /* Get the max length of the command name */ 288 287 for (i=0;i<info->hint_cnt;++i) { 289 if ((&hint[i].type) && (hint[i].type.slen > 0)) { 290 if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 288 if ((&hint[i].type) && (hint[i].type.slen > 0)) { 289 if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 291 290 if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 292 291 cmd_length += (hint[i].name.slen + 3); 293 292 } else { 294 293 cmd_length = hint[i].name.slen; 295 } 294 } 296 295 } else { 297 296 cmd_length = hint[i].name.slen; 298 297 } 299 } else { 298 } else { 300 299 cmd_length = hint[i].name.slen; 301 300 } … … 308 307 cmd_length = 0; 309 308 for (i=0;i<info->hint_cnt;++i) { 310 if ((&hint[i].type) && (hint[i].type.slen > 0)) { 309 if ((&hint[i].type) && (hint[i].type.slen > 0)) { 311 310 if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 312 311 parse_state = OP_SHORTCUT; … … 316 315 parse_state = OP_TYPE; 317 316 } 318 } else { 317 } else { 319 318 parse_state = OP_NORMAL; 320 319 } … … 324 323 cmd_length = hint[i].name.slen; 325 324 } 326 325 327 326 switch (parse_state) { 328 327 case OP_CHOICE: 329 328 pj_strcat2(&send_data, "["); 330 329 pj_strcat(&send_data, &hint[i].name); 331 pj_strcat2(&send_data, "]"); 330 pj_strcat2(&send_data, "]"); 332 331 break; 333 332 case OP_TYPE: 334 333 pj_strcat2(&send_data, "<"); 335 334 pj_strcat(&send_data, &hint[i].type); 336 pj_strcat2(&send_data, ">"); 335 pj_strcat2(&send_data, ">"); 337 336 break; 338 337 case OP_SHORTCUT: 339 338 /* Format : "Command | sc | description" */ 340 { 339 { 341 340 cmd_length += hint[i].name.slen; 342 341 if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 343 342 pj_strcat2(&send_data, " | "); 344 cmd_length += 3; 343 cmd_length += 3; 345 344 } else { 346 345 pj_strcat2(&send_data, "\r\n "); 347 346 } 348 pj_strcat(&send_data, &hint[i].name); 347 pj_strcat(&send_data, &hint[i].name); 349 348 } 350 349 break; 351 350 default: 352 351 pj_strcat(&send_data, &hint[i].name); 353 cmd_desc = &hint[i].desc;354 352 break; 355 353 } 356 357 if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) || 354 355 if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) || 358 356 ((i+1) >= info->hint_cnt) || 359 (pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen))) 357 (pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen))) 360 358 { 361 359 /* Add description info */ … … 364 362 cmd_length = 0; 365 363 } 366 } 364 } 367 365 pj_strcat2(&send_data, "\r\n"); 368 366 pj_strcat(&send_data, &fe->cfg.prompt_str); 369 367 send_data.ptr[send_data.slen] = 0; 370 printf("%s", send_data.ptr); 368 printf("%s", send_data.ptr); 371 369 } 372 370 … … 375 373 pj_status_t status; 376 374 pj_bool_t retval = PJ_TRUE; 377 375 378 376 pj_pool_t *pool; 379 377 pj_cli_cmd_val *cmd_val; … … 388 386 389 387 cmd_val = PJ_POOL_ZALLOC_T(pool, pj_cli_cmd_val); 390 391 status = pj_cli_sess_parse(sess, recv_buf, cmd_val, 388 389 status = pj_cli_sess_parse(sess, recv_buf, cmd_val, 392 390 pool, &info); 393 391 394 392 switch (status) { 395 393 case PJ_CLI_EINVARG: 396 send_inv_arg(sess, &info, PJ_TRUE); 394 send_inv_arg(sess, &info, PJ_TRUE); 397 395 break; 398 396 case PJ_CLI_ETOOMANYARGS: … … 403 401 send_ambi_arg(sess, &info, PJ_TRUE); 404 402 break; 405 case PJ_SUCCESS: 406 if (info.hint_cnt > 0) { 407 /* Compelete command */ 408 send_ambi_arg(sess, &info, PJ_TRUE); 403 case PJ_SUCCESS: 404 if (info.hint_cnt > 0) { 405 /* Compelete command */ 406 send_ambi_arg(sess, &info, PJ_TRUE); 409 407 } else { 410 408 retval = PJ_FALSE; 411 } 412 break; 413 } 414 415 pj_pool_release(pool); 416 return retval; 409 } 410 break; 411 } 412 413 pj_pool_release(pool); 414 return retval; 417 415 } 418 416 … … 421 419 pj_status_t status; 422 420 pj_bool_t retval = PJ_TRUE; 423 424 pj_pool_t *pool; 421 422 pj_pool_t *pool; 425 423 pj_cli_exec_info info; 426 424 pj_cli_t *cli = sess->fe->cli; 427 425 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 428 426 char *recv_buf = fe->input.buf; 429 427 430 428 printf("\r\n"); 431 429 432 430 pool = pj_pool_create(pj_cli_get_param(cli)->pf, "handle_exec", 433 431 PJ_CLI_CONSOLE_POOL_SIZE, PJ_CLI_CONSOLE_POOL_INC, 434 NULL); 435 436 status = pj_cli_sess_exec(sess, recv_buf, 432 NULL); 433 434 status = pj_cli_sess_exec(sess, recv_buf, 437 435 pool, &info); 438 436 439 437 switch (status) { 440 438 case PJ_CLI_EINVARG: 441 send_inv_arg(sess, &info, PJ_FALSE); 439 send_inv_arg(sess, &info, PJ_FALSE); 442 440 break; 443 441 case PJ_CLI_ETOOMANYARGS: … … 452 450 break; 453 451 case PJ_SUCCESS: 454 send_prompt_str(sess); 455 break; 456 } 457 458 pj_pool_release(pool); 459 return retval; 452 send_prompt_str(sess); 453 break; 454 } 455 456 pj_pool_release(pool); 457 return retval; 460 458 } 461 459 462 460 static int readline_thread(void * p) 463 { 461 { 464 462 struct cli_console_fe * fe = (struct cli_console_fe *)p; 465 463 … … 473 471 474 472 if (fgets(recv_buf, fe->input.maxlen, stdin) == NULL) { 475 /* 473 /* 476 474 * Be friendly to users who redirect commands into 477 475 * program, when file ends, resume with kbd. … … 488 486 puts("Cannot switch back to console from file redirection"); 489 487 if (fe->cfg.quit_command.slen) { 490 pj_memcpy(recv_buf, fe->cfg.quit_command.ptr, 488 pj_memcpy(recv_buf, fe->cfg.quit_command.ptr, 491 489 fe->input.maxlen); 492 490 } 493 recv_buf[fe->cfg.quit_command.slen] = '\0'; 491 recv_buf[fe->cfg.quit_command.slen] = '\0'; 494 492 } else { 495 493 puts("Switched back to console from file redirection"); … … 506 504 break; 507 505 } 508 input_len = pj_ansi_strlen(fe->input.buf); 506 input_len = pj_ansi_strlen(fe->input.buf); 509 507 if ((input_len > 1) && (fe->input.buf[input_len-2] == '?')) { 510 508 fe->input.buf[input_len-1] = 0; … … 516 514 } 517 515 518 pj_sem_post(fe->input.sem); 516 pj_sem_post(fe->input.sem); 519 517 pj_sem_wait(fe->thread_sem); 520 } 518 } 521 519 522 520 return 0; 523 521 } 524 522 525 PJ_DEF(pj_status_t) pj_cli_console_process(pj_cli_sess *sess, 523 PJ_DEF(pj_status_t) pj_cli_console_process(pj_cli_sess *sess, 526 524 char *buf, 527 525 unsigned maxlen)
Note: See TracChangeset
for help on using the changeset viewer.