Changeset 4513


Ignore:
Timestamp:
May 3, 2013 8:47:14 AM (11 years ago)
Author:
riza
Message:

Re #1643: - Modification to shortcut handling(execution&display).

  • Add exact match check to the parse input command process.
Location:
pjproject/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjlib-util/cli.c

    r4440 r4513  
    3535#define CLI_CMD_EXIT        30001 
    3636 
     37#define MAX_CMD_HASH_NAME_LENGTH 64 
     38#define MAX_CMD_ID_LENGTH 16 
     39 
    3740#if 1 
    3841    /* Enable some tracing */ 
     
    127130    pj_cli_cmd_spec     root;           /* Root of command tree structure */ 
    128131    pj_cli_front_end    fe_head;        /* List of front-ends */ 
    129     pj_hash_table_t    *cmd_name_hash;  /* Command name hash table */ 
     132    pj_hash_table_t    *cmd_name_hash;  /* Command name hash table, this will  
     133                                           include the command name and shortcut  
     134                                           as hash key */ 
    130135    pj_hash_table_t    *cmd_id_hash;    /* Command id hash table */ 
    131136 
     
    485490} 
    486491 
    487 /* Check if command already added to command hash */ 
    488 static pj_bool_t cmd_name_exists(pj_cli_t *cli, pj_cli_cmd_spec *group,  
    489                                  pj_str_t *cmd) 
     492/* Get the command from the command hash */ 
     493static pj_cli_cmd_spec *get_cmd_name(const pj_cli_t *cli,  
     494                                     const pj_cli_cmd_spec *group,  
     495                                     const pj_str_t *cmd) 
    490496{ 
    491497    pj_str_t cmd_val; 
    492     char cmd_ptr[64]; 
    493  
    494     cmd_val.ptr = &cmd_ptr[0]; 
     498    char cmd_ptr[MAX_CMD_HASH_NAME_LENGTH]; 
     499 
     500    cmd_val.ptr = cmd_ptr; 
    495501    cmd_val.slen = 0; 
    496502 
    497503    if (group) { 
    498         char cmd_str[16]; 
    499         pj_ansi_sprintf(&cmd_str[0], "%d", group->id); 
    500         pj_strcat2(&cmd_val, &cmd_str[0]);       
     504        char cmd_str[MAX_CMD_ID_LENGTH]; 
     505        pj_ansi_sprintf(cmd_str, "%d", group->id); 
     506        pj_strcat2(&cmd_val, cmd_str);   
    501507    } 
    502508    pj_strcat(&cmd_val, cmd); 
    503     return (pj_hash_get(cli->cmd_name_hash,  
    504                         cmd_val.ptr, cmd_val.slen, NULL) != 0); 
     509    return (pj_cli_cmd_spec *)pj_hash_get(cli->cmd_name_hash, cmd_val.ptr,  
     510                                          cmd_val.slen, NULL); 
    505511} 
    506512 
     
    511517    pj_str_t cmd_val; 
    512518    pj_str_t add_cmd; 
    513     char cmd_ptr[64]; 
    514  
    515     cmd_val.ptr = &cmd_ptr[0]; 
     519    char cmd_ptr[MAX_CMD_HASH_NAME_LENGTH]; 
     520 
     521    cmd_val.ptr = cmd_ptr; 
    516522    cmd_val.slen = 0; 
    517523 
    518524    if (group) { 
    519         pj_strcat(&cmd_val, &group->name); 
     525        char cmd_str[MAX_CMD_ID_LENGTH]; 
     526        pj_ansi_sprintf(cmd_str, "%d", group->id); 
     527        pj_strcat2(&cmd_val, cmd_str);   
    520528    } 
    521529    pj_strcat(&cmd_val, cmd_name); 
    522530    pj_strdup(cli->pool, &add_cmd, &cmd_val); 
    523531     
    524     pj_hash_set(cli->pool, cli->cmd_name_hash,  
    525                 cmd_val.ptr, cmd_val.slen, 0, cmd); 
     532    pj_hash_set(cli->pool, cli->cmd_name_hash, cmd_val.ptr,  
     533                cmd_val.slen, 0, cmd); 
    526534} 
    527535 
     
    665673            pj_strltrim(&attr->value); 
    666674            if (!attr->value.slen ||  
    667                 cmd_name_exists(cli, group, &attr->value))                 
     675                (get_cmd_name(cli, group, &attr->value)))                 
    668676            { 
    669677                return PJ_CLI_EBADNAME; 
     
    703711                    } 
    704712                    /* Check whether the shortcuts are already used */ 
    705                     if (cmd_name_exists(cli, group, &str)) { 
     713                    if (get_cmd_name(cli, &cli->root, &str)) { 
    706714                        PJ_THROW(PJ_CLI_EBADNAME); 
    707715                    } 
     
    773781                                             sizeof(pj_str_t)); 
    774782        for (i = 0; i < cmd->sc_cnt; i++) { 
    775             pj_strdup(cli->pool, &cmd->sc[i], &sc[i]); 
    776             add_cmd_name(cli, group, cmd, &sc[i]); 
     783            pj_strdup(cli->pool, &cmd->sc[i], &sc[i]);   
     784            /** Add shortcut to root command **/ 
     785            add_cmd_name(cli, &cli->root, cmd, &sc[i]); 
    777786        } 
    778787    } 
     
    881890                info->err_pos = scanner.curptr - scanner.begin; 
    882891                if (*scanner.curptr == '\'' || *scanner.curptr == '"' || 
    883                     *scanner.curptr == '[' || *scanner.curptr == '{') 
     892                    *scanner.curptr == '{') 
    884893                { 
    885                     pj_scan_get_quotes(&scanner, "'\"[{", "'\"]}", 4, &str); 
     894                    pj_scan_get_quotes(&scanner, "'\"{", "'\"}", 3, &str); 
    886895                    /* Remove the quotes */ 
    887896                    str.ptr++; 
     
    983992} 
    984993 
     994static pj_bool_t hint_inserted(const pj_str_t *name,  
     995                               const pj_str_t *desc,  
     996                               const pj_str_t *type,  
     997                               pj_cli_exec_info *info) 
     998{ 
     999    unsigned i; 
     1000    for(i=0; i<info->hint_cnt; ++i) { 
     1001        pj_cli_hint_info *hint = &info->hint[i]; 
     1002        if ((!pj_strncmp(&hint->name, name, hint->name.slen)) && 
     1003            (!pj_strncmp(&hint->desc, desc, hint->desc.slen)) && 
     1004            (!pj_strncmp(&hint->type, type, hint->type.slen))) 
     1005        { 
     1006            return PJ_TRUE; 
     1007        } 
     1008    } 
     1009    return PJ_FALSE; 
     1010} 
     1011 
     1012/** This will insert new hint with the option to check for the same  
     1013    previous entry **/ 
     1014static pj_status_t insert_new_hint2(pj_pool_t *pool,  
     1015                                    pj_bool_t unique_insert, 
     1016                                    const pj_str_t *name,  
     1017                                    const pj_str_t *desc,  
     1018                                    const pj_str_t *type,  
     1019                                    pj_cli_exec_info *info) 
     1020{ 
     1021    pj_cli_hint_info *hint; 
     1022    PJ_ASSERT_RETURN(pool && info, PJ_EINVAL); 
     1023    PJ_ASSERT_RETURN((info->hint_cnt < PJ_CLI_MAX_HINTS), PJ_EINVAL); 
     1024 
     1025    if ((unique_insert) && (hint_inserted(name, desc, type, info))) 
     1026        return PJ_SUCCESS; 
     1027 
     1028    hint = &info->hint[info->hint_cnt]; 
     1029 
     1030    pj_strdup(pool, &hint->name, name); 
     1031 
     1032    if (desc && (desc->slen > 0))  { 
     1033        pj_strdup(pool, &hint->desc, desc); 
     1034    } else { 
     1035        hint->desc.slen = 0; 
     1036    } 
     1037     
     1038    if (type && (type->slen > 0)) { 
     1039        pj_strdup(pool, &hint->type, type); 
     1040    } else { 
     1041        hint->type.slen = 0; 
     1042    } 
     1043 
     1044    ++info->hint_cnt;     
     1045    return PJ_SUCCESS; 
     1046} 
     1047 
     1048/** This will insert new hint without checking for the same previous entry **/ 
    9851049static pj_status_t insert_new_hint(pj_pool_t *pool,  
    9861050                                   const pj_str_t *name,  
     
    9891053                                   pj_cli_exec_info *info) 
    9901054{         
    991     pj_cli_hint_info *hint; 
    992     PJ_ASSERT_RETURN(pool && info, PJ_EINVAL); 
    993     PJ_ASSERT_RETURN((info->hint_cnt < PJ_CLI_MAX_HINTS), PJ_EINVAL); 
    994     hint = &info->hint[info->hint_cnt]; 
    995  
    996     pj_strdup(pool, &hint->name, name); 
    997  
    998     if (desc && (desc->slen > 0))  { 
    999         pj_strdup(pool, &hint->desc, desc); 
    1000     } else { 
    1001         hint->desc.slen = 0; 
    1002     } 
    1003      
    1004     if (type && (type->slen > 0)) { 
    1005         pj_strdup(pool, &hint->type, type); 
    1006     } else { 
    1007         hint->type.slen = 0; 
    1008     } 
    1009  
    1010     ++info->hint_cnt;     
     1055    return insert_new_hint2(pool, PJ_FALSE, name, desc, type, info); 
     1056} 
     1057 
     1058/** This will get a complete/exact match of a command from the cmd hash **/ 
     1059static pj_status_t get_comp_match_cmds(const pj_cli_t *cli,  
     1060                                       const pj_cli_cmd_spec *group, 
     1061                                       const pj_str_t *cmd_val,  
     1062                                       pj_pool_t *pool,  
     1063                                       pj_cli_cmd_spec **p_cmd, 
     1064                                       pj_cli_exec_info *info) 
     1065{ 
     1066    pj_cli_cmd_spec *cmd;     
     1067    PJ_ASSERT_RETURN(cli && group && cmd_val && pool && info, PJ_EINVAL);    
     1068 
     1069    cmd = get_cmd_name(cli, group, cmd_val); 
     1070 
     1071    if (cmd) { 
     1072        pj_status_t status;     
     1073        status = insert_new_hint(pool, cmd_val, &cmd->desc, NULL, info); 
     1074 
     1075        if (status != PJ_SUCCESS) 
     1076            return status; 
     1077 
     1078        *p_cmd = cmd; 
     1079    } 
     1080 
    10111081    return PJ_SUCCESS; 
    10121082} 
    10131083 
    1014 static pj_status_t get_match_cmds(pj_cli_cmd_spec *cmd,  
    1015                                   const pj_str_t *cmd_val,                                     
    1016                                   pj_pool_t *pool,  
    1017                                   pj_cli_cmd_spec **p_cmd,                              
    1018                                   pj_cli_exec_info *info) 
    1019 { 
    1020     pj_status_t status = PJ_SUCCESS; 
    1021     PJ_ASSERT_RETURN(cmd && pool && info && cmd_val, PJ_EINVAL);     
     1084/** This method will search for any shortcut with pattern match to the input 
     1085    command. This method should be called from root command, as shortcut could 
     1086    only be executed from root **/ 
     1087static pj_status_t get_pattern_match_shortcut(const pj_cli_t *cli, 
     1088                                              const pj_str_t *cmd_val, 
     1089                                              pj_pool_t *pool,  
     1090                                              pj_cli_cmd_spec **p_cmd, 
     1091                                              pj_cli_exec_info *info) 
     1092{ 
     1093    pj_hash_iterator_t it_buf, *it; 
     1094    pj_status_t status; 
     1095    PJ_ASSERT_RETURN(cli && pool && cmd_val && info, PJ_EINVAL); 
     1096   
     1097    it = pj_hash_first(cli->cmd_name_hash, &it_buf); 
     1098    while (it) { 
     1099        unsigned i; 
     1100        pj_cli_cmd_spec *cmd = (pj_cli_cmd_spec *) 
     1101                               pj_hash_this(cli->cmd_name_hash, it); 
     1102 
     1103        PJ_ASSERT_RETURN(cmd, PJ_EINVAL);            
     1104         
     1105        for (i=0; i < cmd->sc_cnt; ++i) { 
     1106            static const pj_str_t SHORTCUT = {"SC", 2}; 
     1107            pj_str_t *sc = &cmd->sc[i]; 
     1108            PJ_ASSERT_RETURN(sc, PJ_EINVAL); 
     1109 
     1110            if (!pj_strncmp(sc, cmd_val, cmd_val->slen)) { 
     1111                /** Unique hints needed because cmd hash contain command name 
     1112                    and shortcut referencing to the same command **/ 
     1113                status = insert_new_hint2(pool, PJ_TRUE, sc, &cmd->desc,  
     1114                                          &SHORTCUT, info); 
     1115                if (status != PJ_SUCCESS) 
     1116                    return status; 
     1117 
     1118                if (p_cmd) 
     1119                    *p_cmd = cmd; 
     1120            } 
     1121        } 
     1122         
     1123        it = pj_hash_next(cli->cmd_name_hash, it); 
     1124    } 
     1125 
     1126    return PJ_SUCCESS; 
     1127} 
     1128 
     1129/** This method will search a pattern match to the input command from the child 
     1130    command list of the current/active command. **/ 
     1131static pj_status_t get_pattern_match_cmds(pj_cli_cmd_spec *cmd,  
     1132                                          const pj_str_t *cmd_val,                                     
     1133                                          pj_pool_t *pool,  
     1134                                          pj_cli_cmd_spec **p_cmd,  
     1135                                          pj_cli_parse_mode parse_mode, 
     1136                                          pj_cli_exec_info *info) 
     1137{ 
     1138    pj_status_t status; 
     1139    PJ_ASSERT_RETURN(cmd && pool && info && cmd_val, PJ_EINVAL);    
    10221140 
    10231141    if (p_cmd) 
     
    10281146        pj_cli_cmd_spec *child_cmd = cmd->sub_cmd->next; 
    10291147        while (child_cmd != cmd->sub_cmd) { 
    1030             unsigned i;     
    10311148            pj_bool_t found = PJ_FALSE; 
    10321149            if (!pj_strncmp(&child_cmd->name, cmd_val, cmd_val->slen)) {                 
     
    10381155                found = PJ_TRUE; 
    10391156            } 
    1040             for (i=0; i < child_cmd->sc_cnt; ++i) { 
    1041                 static const pj_str_t SHORTCUT = {"SC", 2}; 
    1042                 pj_str_t *sc = &child_cmd->sc[i]; 
    1043                 PJ_ASSERT_RETURN(sc, PJ_EINVAL); 
    1044  
    1045                 if (!pj_strncmp(sc, cmd_val, cmd_val->slen)) {           
    1046                     status = insert_new_hint(pool, sc, &child_cmd->desc,  
    1047                                              &SHORTCUT, info); 
    1048                     if (status != PJ_SUCCESS) 
    1049                         return status; 
    1050  
    1051                     found = PJ_TRUE; 
    1052                 }                
    1053             } 
    1054             if (found && p_cmd)  
    1055                 *p_cmd = child_cmd;                          
    1056  
     1157            if (found) { 
     1158                if (parse_mode == PARSE_NEXT_AVAIL) { 
     1159                    /** Only insert shortcut on next available commands mode **/ 
     1160                    unsigned i; 
     1161                    for (i=0; i < child_cmd->sc_cnt; ++i) { 
     1162                        static const pj_str_t SHORTCUT = {"SC", 2}; 
     1163                        pj_str_t *sc = &child_cmd->sc[i]; 
     1164                        PJ_ASSERT_RETURN(sc, PJ_EINVAL); 
     1165 
     1166                        status = insert_new_hint(pool, sc,  
     1167                                                 &child_cmd->desc, &SHORTCUT,  
     1168                                                 info); 
     1169                        if (status != PJ_SUCCESS) 
     1170                            return status; 
     1171                    } 
     1172                } 
     1173 
     1174                if (p_cmd) 
     1175                    *p_cmd = child_cmd;                      
     1176            }    
    10571177            child_cmd = child_cmd->next; 
    10581178        } 
    10591179    } 
    1060     return status; 
    1061 } 
    1062  
     1180    return PJ_SUCCESS; 
     1181} 
     1182 
     1183/** This will match the arguments passed to the command with the argument list 
     1184    of the specified command list. **/ 
    10631185static pj_status_t get_match_args(pj_cli_sess *sess, 
    10641186                                  pj_cli_cmd_spec *cmd,  
     
    10891211            if ((parse_mode == PARSE_EXEC) && (!arg->validate)) { 
    10901212                /* If no validation needed, then insert the values */ 
    1091                 status = insert_new_hint(pool,  
    1092                                          cmd_val,  
    1093                                          NULL,  
    1094                                          NULL, 
    1095                                          info);          
     1213                status = insert_new_hint(pool, cmd_val, NULL, NULL, info);               
    10961214                return status; 
    10971215            } 
     
    11651283} 
    11661284 
     1285/** This will check for a match of the commands/arguments input. Any match  
     1286    will be inserted to the hint data. **/ 
    11671287static pj_status_t get_available_cmds(pj_cli_sess *sess, 
    11681288                                      pj_cli_cmd_spec *cmd,  
     
    11831303    info->hint_cnt = 0;     
    11841304 
    1185     if (get_cmd) 
    1186         status = get_match_cmds(cmd, prefix, pool, p_cmd, info); 
     1305    if (get_cmd) { 
     1306        status = get_comp_match_cmds(sess->fe->cli, cmd, prefix, pool, p_cmd,  
     1307                                     info); 
     1308        if (status != PJ_SUCCESS) 
     1309            return status; 
     1310         
     1311        /** If exact match found, then no need to search for pattern match **/ 
     1312        if (info->hint_cnt == 0) { 
     1313            if ((parse_mode != PARSE_NEXT_AVAIL) &&  
     1314                (cmd == &sess->fe->cli->root))  
     1315            { 
     1316                /** Pattern match for shortcut needed on root command only **/ 
     1317                status = get_pattern_match_shortcut(sess->fe->cli, prefix, pool, 
     1318                                                    p_cmd, info); 
     1319 
     1320                if (status != PJ_SUCCESS) 
     1321                    return status; 
     1322            } 
     1323 
     1324            status = get_pattern_match_cmds(cmd, prefix, pool, p_cmd,  
     1325                                            parse_mode, info); 
     1326        } 
     1327 
     1328        if (status != PJ_SUCCESS) 
     1329            return status; 
     1330    } 
     1331 
    11871332    if (argc > 0) 
    11881333        status = get_match_args(sess, cmd, prefix, argc,  
     
    11911336    if (status == PJ_SUCCESS) {  
    11921337        if (prefix->slen > 0) { 
     1338            /** If a command entered is not a an empty command, and have a  
     1339                single match in the command list then it is a valid command **/ 
    11931340            if (info->hint_cnt == 0) { 
    11941341                status = PJ_CLI_EINVARG; 
  • pjproject/trunk/pjlib-util/src/pjlib-util/cli_console.c

    r4484 r4513  
    182182    struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 
    183183 
    184     send_data.ptr = &data_str[0]; 
     184    send_data.ptr = data_str; 
    185185    send_data.slen = 0; 
    186186     
     
    202202    struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 
    203203 
    204     send_data.ptr = &data_str[0]; 
     204    send_data.ptr = data_str; 
    205205    send_data.slen = 0; 
    206206 
     
    273273    static const pj_str_t sc_type = {"sc", 2}; 
    274274    static const pj_str_t choice_type = {"choice", 6}; 
    275     send_data.ptr = &data[0]; 
     275    send_data.ptr = data; 
    276276    send_data.slen = 0; 
    277277     
     
    288288    for (i=0;i<info->hint_cnt;++i) { 
    289289        if ((&hint[i].type) && (hint[i].type.slen > 0)) {            
    290             if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 
    291                 //Additional delimiter " | " 
    292                 cmd_length += (hint[i].name.slen + 3); 
     290            if (pj_stricmp(&hint[i].type, &sc_type) == 0) {              
     291                if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 
     292                    cmd_length += (hint[i].name.slen + 3); 
     293                } else { 
     294                    cmd_length = hint[i].name.slen; 
     295                }                
    293296            } else { 
    294297                cmd_length = hint[i].name.slen; 
     
    304307 
    305308    cmd_length = 0; 
    306     for (i=0;i<info->hint_cnt;++i) {     
     309    for (i=0;i<info->hint_cnt;++i) { 
    307310        if ((&hint[i].type) && (hint[i].type.slen > 0)) {            
    308311            if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 
     
    317320        } 
    318321 
    319         if ((parse_state != OP_SHORTCUT)) { 
    320             if (cmd_desc) { 
    321                 /* Print data if previous hint is shortcut */ 
    322                 send_hint_arg(&send_data, cmd_desc, cmd_length, max_length); 
    323                 cmd_desc = 0; 
    324             } 
     322        if (parse_state != OP_SHORTCUT) { 
    325323            pj_strcat2(&send_data, "\r\n  "); 
    326324            cmd_length = hint[i].name.slen; 
     
    338336            pj_strcat2(&send_data, ">");         
    339337            break; 
    340         case OP_SHORTCUT:            
    341             pj_strcat2(&send_data, " | "); 
    342             pj_strcat(&send_data, &hint[i].name); 
    343             cmd_length += (hint[i].name.slen + 3); 
     338        case OP_SHORTCUT: 
     339            /* Format : "Command | sc |  description" */ 
     340            {            
     341                cmd_length += hint[i].name.slen; 
     342                if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 
     343                    pj_strcat2(&send_data, " | "); 
     344                    cmd_length += 3;                 
     345                } else { 
     346                    pj_strcat2(&send_data, "\r\n  "); 
     347                } 
     348                pj_strcat(&send_data, &hint[i].name);    
     349            } 
    344350            break; 
    345351        default: 
     
    350356         
    351357        if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) ||  
    352             ((i+1) >= info->hint_cnt))  
     358            ((i+1) >= info->hint_cnt) || 
     359            (pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen)))  
    353360        { 
    354361            /* Add description info */ 
    355362            send_hint_arg(&send_data, &hint[i].desc, cmd_length, max_length); 
     363 
     364            cmd_length = 0; 
    356365        } 
    357366    }   
  • pjproject/trunk/pjlib-util/src/pjlib-util/cli_telnet.c

    r4476 r4513  
    668668    cli_telnet_fe *fe = (cli_telnet_fe *)sess->base.fe; 
    669669 
    670     send_data.ptr = &data_str[0]; 
     670    send_data.ptr = data_str; 
    671671    send_data.slen = 0; 
    672672     
     
    692692    cli_telnet_fe *fe = (cli_telnet_fe *)sess->base.fe; 
    693693 
    694     send_data.ptr = &data_str[0]; 
     694    send_data.ptr = data_str; 
    695695    send_data.slen = 0; 
    696696 
     
    709709    pj_strcat(&send_data, &fe->cfg.prompt_str); 
    710710    if (with_last_cmd) 
    711         pj_strcat2(&send_data, (char *)&sess->rcmd->rbuf[0]); 
     711        pj_strcat2(&send_data, (char *)sess->rcmd->rbuf); 
    712712 
    713713    telnet_sess_send(sess, &send_data); 
     
    772772    static const pj_str_t sc_type = {"sc", 2}; 
    773773    static const pj_str_t choice_type = {"choice", 6}; 
    774     send_data.ptr = &data[0]; 
     774    send_data.ptr = data; 
    775775    send_data.slen = 0; 
    776776     
     
    787787    for (i=0;i<info->hint_cnt;++i) { 
    788788        if ((&hint[i].type) && (hint[i].type.slen > 0)) {            
    789             if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 
    790                 //Additional delimiter " | " 
    791                 cmd_length += (hint[i].name.slen + 3); 
     789            if (pj_stricmp(&hint[i].type, &sc_type) == 0) {              
     790                if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 
     791                    cmd_length += (hint[i].name.slen + 3); 
     792                } else { 
     793                    cmd_length = hint[i].name.slen; 
     794                }                
    792795            } else { 
    793796                cmd_length = hint[i].name.slen; 
     
    817820        } 
    818821         
    819         if ((parse_state != OP_SHORTCUT)) { 
    820             if (cmd_desc) { 
    821                 /* Print data if previous hint is shortcut */ 
    822                 send_hint_arg(sess, &send_data,  
    823                               cmd_desc, cmd_length,  
    824                               max_length); 
    825                 cmd_desc = 0; 
    826             } 
     822        if (parse_state != OP_SHORTCUT) { 
    827823            pj_strcat2(&send_data, "\r\n  "); 
    828824            cmd_length = hint[i].name.slen; 
    829         } 
    830  
     825        }            
     826         
    831827        switch (parse_state) { 
    832828        case OP_CHOICE: 
     
    844840        case OP_SHORTCUT: 
    845841            /* Format : "Command | sc |  description" */ 
    846             pj_strcat2(&send_data, " | "); 
    847             pj_strcat(&send_data, &hint[i].name); 
    848             cmd_length += (hint[i].name.slen + 3); 
     842            {            
     843                cmd_length += hint[i].name.slen; 
     844                if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) { 
     845                    pj_strcat2(&send_data, " | "); 
     846                    cmd_length += 3;                 
     847                } else { 
     848                    pj_strcat2(&send_data, "\r\n  "); 
     849                } 
     850                pj_strcat(&send_data, &hint[i].name);    
     851            } 
    849852            break; 
    850853        default: 
     
    856859         
    857860        if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) ||  
    858             ((i+1) >= info->hint_cnt))  
     861            ((i+1) >= info->hint_cnt) || 
     862            (pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen)))  
    859863        { 
    860864            /* Add description info */ 
     
    862866                          &hint[i].desc, cmd_length,  
    863867                          max_length); 
     868 
     869            cmd_length = 0; 
    864870        }        
    865871    }   
     
    867873    pj_strcat(&send_data, &fe->cfg.prompt_str); 
    868874    if (with_last_cmd) 
    869         pj_strcat2(&send_data, (char *)&sess->rcmd->rbuf[0]); 
     875        pj_strcat2(&send_data, (char *)sess->rcmd->rbuf); 
    870876 
    871877    telnet_sess_send(sess, &send_data);     
     
    883889    pj_strcat2(&info->hint[0].name, " "); 
    884890 
    885     send_data.ptr = &data[0]; 
     891    send_data.ptr = data; 
    886892    send_data.slen = 0; 
    887893 
     
    901907            unsigned char echo[5] = {0x1b, 0x5b, 0x31, 0x40, 0x00}; 
    902908            echo[4] = *data; 
    903             telnet_sess_send2(sess, &echo[0], 5); 
     909            telnet_sess_send2(sess, echo, 5); 
    904910        } else { 
    905911            /* Append character */ 
     
    925931            unsigned char echo[5] = {0x00, 0x1b, 0x5b, 0x31, 0x50}; 
    926932            echo[0] = *data; 
    927             telnet_sess_send2(sess, &echo[0], 5); 
     933            telnet_sess_send2(sess, echo, 5); 
    928934        } else { 
    929935            const static unsigned char echo[3] = {0x08, 0x20, 0x08};         
    930             telnet_sess_send2(sess, &echo[0], 3); 
     936            telnet_sess_send2(sess, echo, 3); 
    931937        } 
    932938        return PJ_TRUE; 
     
    987993                               pool, &info);     
    988994 
    989     len = pj_ansi_strlen((char *)&sess->rcmd->rbuf[0]); 
     995    len = pj_ansi_strlen((char *)sess->rcmd->rbuf); 
    990996 
    991997    switch (status) { 
     
    10101016        if (info.hint_cnt > 0) {         
    10111017            /* Complete command */ 
    1012             pj_str_t cmd = pj_str((char *)&sess->rcmd->rbuf[0]); 
     1018            pj_str_t cmd = pj_str((char *)sess->rcmd->rbuf); 
    10131019            pj_str_t last_token; 
    10141020 
     
    10191025                if (hint_info->slen >= last_token.slen) { 
    10201026                    hint_info->slen -= last_token.slen; 
    1021                     pj_memmove(&hint_info->ptr[0],  
     1027                    pj_memmove(hint_info->ptr,  
    10221028                               &hint_info->ptr[last_token.slen],  
    10231029                               hint_info->slen);                     
     
    10251031                send_comp_arg(sess, &info); 
    10261032 
    1027                 pj_memcpy(&sess->rcmd->rbuf[len], &info.hint[0].name.ptr[0],  
     1033                pj_memcpy(&sess->rcmd->rbuf[len], info.hint[0].name.ptr,  
    10281034                          info.hint[0].name.slen); 
    10291035 
     
    11361142            CLEAR_CHAR = 0x20 
    11371143        }; 
    1138         send_data.ptr = &str[0]; 
     1144        send_data.ptr = str; 
    11391145        send_data.slen = 0; 
    11401146 
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app_cli.c

    r4489 r4513  
    246246        /* Main loop for CLI FE console */ 
    247247        while (!pj_cli_is_quitting(cli)) { 
    248             pj_cli_console_process(cli_cons_sess, &cmdline[0], sizeof(cmdline)); 
     248            pj_cli_console_process(cli_cons_sess, cmdline, sizeof(cmdline)); 
    249249        } 
    250250    } else if (wait_telnet_cli) { 
     
    26322632    char* call_command =  
    26332633        "<CMD name='call' id='100' desc='Call related commands'>" 
    2634         "  <CMD name='new' id='1001' desc='Show Help'>" 
     2634        "  <CMD name='new' id='1001' desc='Make a new call/INVITE'>" 
    26352635        "    <ARG name='buddy_id' type='choice' id='9901' validate='0' " 
    26362636        "     desc='Buddy Id'>" 
     
    26582658        "   desc='Re-invite (release hold)'/>" 
    26592659        "  <CMD name='update' id='1008' sc='U' desc='Send Update request'/>" 
    2660         "  <CMD name='next' id='1009' sc='>' desc='Select next call'/>" 
    2661         "  <CMD name='previous' id='1010' sc='<' desc='Select previous call'/>" 
     2660        "  <CMD name='next' id='1009' sc=']' desc='Select next call'/>" 
     2661        "  <CMD name='previous' id='1010' sc='[' desc='Select previous call'/>" 
    26622662        "  <CMD name='transfer' id='1011' sc='x' desc='Transfer call'>" 
    26632663        "    <ARG name='buddy_id' type='choice' id='9901' validate='0' " 
     
    27512751        "    </ARG>" 
    27522752        "  </CMD>" 
    2753         "  <CMD name='bud_list' id='2008' sc='l' desc='Show buddy list'/>" 
     2753        "  <CMD name='bud_list' id='2008' sc='bl' desc='Show buddy list'/>" 
    27542754        "</CMD>"; 
    27552755 
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app_config.c

    r4489 r4513  
    524524 
    525525    cfg->acc_cnt = 0; 
    526     cur_acc = &cfg->acc_cfg[0]; 
     526    cur_acc = cfg->acc_cfg; 
    527527 
    528528 
Note: See TracChangeset for help on using the changeset viewer.