免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5019 | 回复: 23

g-bios command option auto-completion [复制链接]

论坛徽章:
0
发表于 2010-09-20 11:03 |显示全部楼层
Description:
    实现g-bios对command option的自动补全

Team member:
    LinColn Shaw、Cassed Chen、Rover Mo、Jonny

论坛徽章:
0
发表于 2010-09-20 11:32 |显示全部楼层
本帖最后由 cassel96 于 2010-09-23 10:21 编辑

实现g-bios对command option的自动补全思路

在struct gapp里面新增一个数组指针option,用于指向app里面命令的参数(二维数组)。确定某一个命令以后,遍历option就可以匹配参数然后补全了。
struct gapp
{
        const char *name;
        int (*main)(int argc, char *argv[]);
        char (*option)[OPTION_LEN];
};
这里是给每个结构体对象赋值的宏
#define INSTALL_APPLICATION(app_name, app_main,app_option) \
        static const __USED__ __GBIOS_APP__ struct gapp __gbios_app_##app_name = {.name = #app_name, .main = app_main, .option = app_option}

比如说我们在应用程序ls.c里面有:
static char __app_option[][OPTION_LEN] = {"a", "l", "h", "0"};
…..
INSTALL_APPLICATION(ls, main, __app__option)

如果app没有static char option[][OPTION_LEN],则通过Makefile给该app文件加一句:
static char __app_option[][OPTION_LEN];

论坛徽章:
0
发表于 2010-09-20 22:03 |显示全部楼层
本帖最后由 cassel96 于 2010-09-23 10:22 编辑

今天我们小组基本上实现了命令参数补全功能,调试了很久,但是teamwork的力量是很强大的!

opt_match函数实现参数补全, 参数补全算法参考命令补全算法。
cmd_line_status函数用于确定到底是命令补全还是参数补全,当用户输入tab键的时候,进行判断。

static char option[][OPTION_LEN] = {"a", "l", "h", "0"};其中的0是用来控制循环退出的。
我们修改了原有的API函数:insert_one_key,backspace_one_key,insert_one_key函数插入的位置不对,backspace_one_key函数虽然退格了,但是没有删除最后那个字符。



现在存在的问题:Makefile还没有修改好,这个Makefile在build/rules/app.mk

论坛徽章:
0
发表于 2010-09-21 17:59 |显示全部楼层
本帖最后由 cassel96 于 2010-09-23 09:55 编辑

0001-command-option-auto-complementation.patch.gz (2.74 KB, 下载次数: 14)

论坛徽章:
0
发表于 2010-09-22 00:37 |显示全部楼层
本帖最后由 jonny2010 于 2010-09-30 19:59 编辑

0001-g-bios-command-option-auto-completion.patch.gz (3.6 KB, 下载次数: 19)

论坛徽章:
0
发表于 2010-09-27 11:06 |显示全部楼层
原来的命令补全还存在bug:当命令前有空格的时候,按tab键不能补全命令.此bug正在fixing......

论坛徽章:
0
发表于 2010-09-28 21:31 |显示全部楼层
本帖最后由 jonny2010 于 2010-09-28 21:33 编辑

昨天发现的2个bug加一个功能拓展已经解决了:
bug 1:见6楼
bug 2:当光标左移到在'-'的前面的时候,依然会被当作是是命令选现补齐
bug 3:当你是选择命令参数补全时,光标总会跳转到字符的最后面
功能拓展:为用户提供一个自己实现opt_match()的接口

解决方法:
bug 1:
我们只需要计算出命令前面空格数space_len,接着后面在buf里面都是以space_len位置处起作匹配

bug 2:
当我们光标前移的时候,当命令里面有‘-’,我们只需分析光标前面的字符串即可;

bug 3::
就是当我们确定用户是命令选项补齐的时候,而进入执行opt_match()这个函数,此时先求出光标到字符串最大长度之间的长度len = *max_pos - *cur_pos;
之后当我们执行完命令选项补齐之后,只要把光标后移到*max_pos - len这个位置就可以了,此时光标就可以达到正确位置了

功能拓展:
今天主要是在app.mk脚本里面卡住了,前面主要是不支持if [  ]; then ;fi   然后我们就一直想在makefie中使用分支语句来实现,但是经过很多的测试发现,很多bash的语法在makefie中是不能使用的;
后来小组成员 LinColn Shaw想出了一个办法,具体方法如下:
@grep "__app_usr_opt_match" __temp_gapp_$^ > /dev/null || echo "INSTALL_APPLICATION($*, main, __app_option, NULL);" >> __temp_gapp_$^   
@grep "INSTALL_APPLICATION($*, main, __app_option, NULL);" __temp_gapp_$^ > /dev/null || echo "INSTALL_APPLICATION($*, main, __app_option, __app_usr_opt_match);    " >> __temp_gapp$^
他的思想主要是:把上一次执行的grep的结果作为本次grep的条件,这样就很好的绕过分支语句了,从而结果就出来了;
然后我们测试的时候,主要是先确定是否存在用户定义的opt_match();要是存在,我们去执行用户的opt_match(),并且打印从shell.c里面传出来的数据:buf,  *cur_pos,  *cur_max
测试结果如我们猜测的一样


最后,虽然我们基本完成了auto_option的功能,但是还是不能解决多个参数补齐,比如: grep -xx -xx   ,里面只能补齐第一个命令选项,当用户的命令中出现了两个不连续的“-”时,则不能再补齐最后一个“-”的请求
但是我想到一个解决方法就是:我们不用从buf里面开始的第一个字母开始来分析,我们只需从光标处开始往回分析字符串就可以实现多个命令选项补齐了!(仅供参考)

论坛徽章:
0
发表于 2010-09-28 22:20 |显示全部楼层
[fly]为了能够在g-bios里应用程序有自己的特殊的命令参数补全接口(可以给应用程序自己实现命令补全),在app.h 的
struct gapp
{
        const char *name;
        int (*main)(int argc, char *argv[]);
        char (*option)[CMD_OPTION_LEN];
        int (*usr_opt_match)(char *buf, int *cur_pos, int *cur_max);
};
里增加了int (*usr_opt_match)(char *buf, int *cur_pos, int *cur_max);加了以后,要解决的问题就是如何根据应用程序是否写了自己命令参数补全而给usr_opt_match赋不同的值(如应用程序没实现命令参数补全就让 usr_opt_match 为NULL 否则赋值为应用程序自己实现的__app_usr_opt_match ),这样在相应table键时就可根据gapp结构体里的usr_opt_match是否为NULL调用不同的命令参数相应函数!

要根据代码是否含有__app_usr_opt_match 而给usr_opt_match赋不同的值,可以想到可以在app对应的makefile里做这些工作(在没有compile之前)!
所以在/g-bios/build/rules/app.mk 里增加了
@grep "__app_usr_opt_match" __temp_gapp_$^ > /dev/null || echo "INSTALL_APPLICATION($*, main, __app_option, NULL);" >> __temp_gapp_$^
@grep "INSTALL_APPLICATION($*, main, __app_option, NULL);"  __temp_gapp_$^ > /dev/null || echo "INSTALL_APPLICATION($*, main, __app_option, __app_usr_opt_match);" >> __temp_gapp_$^

这样就能够很好的保证里应用程序都可以有自己的特殊命令参数补全接口!!
[/fly]

论坛徽章:
0
发表于 2010-09-29 13:12 |显示全部楼层
本帖最后由 jonny2010 于 2010-09-29 13:39 编辑

今天早上进行测试时候,我们小组发现的bug:
bug 1、命令前面有空格时,在app里面有几个跟这个命令相同的命令的时候,保存用户输入的buf里面会把数据保存顺序出错   如:输入:   optmatch  -  会被保存为:    match   opt  -      
bug 2、当判断用户app里面是否有用户自定义的opt_macth()这个函数的时候,匹配app->name时出错了!

解决方法:
bug 1:
主要是在我们补齐命令选项的时候,cur_pos 控制出错,不能正确的把补齐的命令选项加进buf里面;
所以我们从intser_one_key()这个函数进行测试,最后发现*cur_max  与 *cur_pos这个值不相等(本来这两个值在光标没有手动移动过时候是在相等的),所以我们知道是此函数调用时,数据处理出错,然后我们就往上寻找;原来是我们的空格处理时存在bug......导致*cur_pox  与  *cur_max不等。找到问题所在,然后调整一下处理方法即可解决....

bug 2:
主要是对用户输入的cmd  和  放在自定义段里面 app_name  没有进行完全匹配,就去判断用户app中是否存在opt_match(),导致当前应用程序里面有几个跟用户此时输入cmd前端完全匹配时:如:
(1)boot -    (2)boot123 -  (3)boot123456  -         app目录下存在上面的应用程序时,用户输入"boot -" 时,由strncmp(app->name, cmd_buf, strlen(cmd_buf))的匹配没有达到完整的匹配,我们把之改为: strncmp(app->name, cmd_buf, strlen(cmd_buf)) && strlen(app->name) == strlen(cmd_buf)  即可解决

论坛徽章:
0
发表于 2010-09-29 14:11 |显示全部楼层
现在我们组在对现在的代码做一些修改工作
1.CodingStyle
2.该封装的封装成函数,
    如static int __INLINE__ get_pre_space_count(char *buf),static int __INLINE__ get_mid_space_count(char *buf)
3.把较长的计算用一个变量代替,并且这种计算几处地方要用到,pre_opt_len = strlen(cmd_buf) + pre_space_count + mid_space_count + 1;
4.修改API,使得函数名,参数相匹配static int opt_match(char *buf, int *cur_pos, int *cur_max),static int cmd_match(char *buf, int *cur_pos, int *cur_max)
5.减少耦合,在函数static int cmd_line_status(char *buf, int *cur_pos)中只实现与函数名相应的功能,而不做其他事情。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP