Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correctly handle options like '-f a.txt' #251

Closed
wants to merge 1 commit into from

Conversation

duyanning
Copy link
Contributor

  • Before adding new features and new modules, please go to issues to submit the relevant feature description first.
  • Write good commit messages and use the same coding conventions as the rest of the project.
  • Please commit code to dev branch and we will merge into master branch in feature
  • Ensure your edited codes with four spaces instead of TAB.

  • 增加新特性和新模块之前,请先到issues提交相关特性说明,经过讨论评估确认后,再进行相应的代码提交,避免做无用工作。
  • 编写友好可读的提交信息,并使用与工程代码相同的代码规范,代码请用4个空格字符代替tab缩进。
  • 请提交代码到dev分支,如果通过,我们会在特定时间合并到master分支上。
  • 为了规范化提交日志的格式,commit消息,不要用中文,请用英文描述。

// renamed to tb_normalized_option_done because it can only
// handle normalized options (i.e., options like '-f=a.txt').
// In the style of tbox, use norm instead of normalized
ok = tb_norm_option_done(option, argc, argv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不能这么改,只能在 tb_option_done 一次性处理解析所有,不要分两个接口

*
* @return tb_true or tb_false
*/
tb_bool_t tb_norm_option_done(tb_option_ref_t option, tb_size_t argc, tb_char_t** argv);
Copy link
Member

@waruqi waruqi Dec 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

所以接口都是 tb_option_ 开头的,另外就一个参数解析,不要加新接口

而且这里改了名,还会 break 现有用户


// Prints the command-line arguments before normalization
// tb_trace_i("OLD:");
// tb_print_argv(argc, argv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无关注释删了


// Normalize the parameters, i.e., transform the form '-f a.txt' into the form '-f=a.txt'
// Make a two-dimensional character array to hold command-line arguments
// The number of first dimensions will not exceed 'argc'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

多行注释用 /* */

// (why +1, because of the equal sign)
// Let's find out how long the longest argv[i] is
tb_size_t i = 0;
tb_size_t longest = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中间不要空这么多

// Allocate space
tb_char_t* data = tb_malloc(argc * (2*longest+1+1)); // including the trailing '\0'
// Allocate space for normalized argv array. Array elements are of tb_char_t*
tb_char_t** new_argv = tb_malloc(argc * sizeof (tb_char_t*));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥解析个参数,还要两次分配。尽量保证 无分配解析

Copy link
Contributor Author

@duyanning duyanning Dec 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其他地方我都可以按您的修改意见进行修改,
但这块不分配内存我好像搞不定。

为了尽可能地避免与您之前的实现在行为上产生细微差异,从而打破tbox用户的已有代码,
我选择了这样一种做法:
先将
-f a.txt -h file0 -f=b.txt file1 --config c.txt file2 --config=d.txt file3 -f -h file4
(其中-f、--config带参数,-h不带参数)
这种形式的命令行参数规范化为
-f=a.txt -h file0 -f=b.txt file1 --config=c.txt file2 --config=d.txt file3 -f -h file4
这种形式,(即给该加等号的地方加上等号)
然后直接调用您原来的接口进行解析。

我两次分配内存,都是为了不影响用户已有的代码。
一次是为规划化后的argv[]数组分配空间,
一次是为规范化后的argv[]数组各元素所指字符串分配空间。
规范化后的argv[]数组的元素个数可能少于原来的argv[]数组,
数组各个元素所指的字符串可能也不同于原来的原来的argv[]数组。

例如:
原来的argv[]数组长这样:

argc: 14
argv[0]: -f
argv[1]: a.txt
argv[2]: -h
argv[3]: file0
argv[4]: -f=b.txt
argv[5]: file1
argv[6]: --config
argv[7]: c.txt
argv[8]: file2
argv[9]: --config=d.txt
argv[10]: file3
argv[11]: -f
argv[12]: -h
argv[13]: file4

规范化后长这样:

argc: 12
argv[0]: -f=a.txt
argv[1]: -h
argv[2]: file0
argv[3]: -f=b.txt
argv[4]: file1
argv[5]: --config=c.txt
argv[6]: file2
argv[7]: --config=d.txt
argv[8]: file3
argv[9]: -f
argv[10]: -h
argv[11]: file4

Copy link
Contributor Author

@duyanning duyanning Dec 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥解析个参数,还要两次分配。尽量保证 无分配解析

算了,我放弃。
我才发现对于类型为 TB_OPTION_TYPE_BOOL 的key,
其后可跟可不跟val,不跟默认true。
不分配内存,在原地解析,
复杂度超出我的预期,不想在这上面花时间了。

感谢ruki长久以来的艰辛工作。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

那你关了吧,或者可以用一些现成的解析库,xmake-repo 上面一堆了。。

ruki-2:xmake-repo ruki$ xrepo search opt
The package names:
    opt:
      -> popt-1.19: C library for parsing command line parameters (in xmake-repo)
      -> docopt-v0.6.3: Pythonic command line arguments parser (C++11 port) (in xmake-repo)
      -> cxxopts-v3.1.1: Lightweight C++ command line option parser (in xmake-repo)
      -> cgetopt-1.0: A GNU getopt() implementation written in pure C. (in xmake-repo)
      -> cargs-v1.0.3: A lightweight cross-platform getopt alternative that works on Linux, Wind
ows and macOS. Command line argument parser library for C/C++. Can be used to parse argv and arg
c parameters. (in xmake-repo)

{
tb_trace_i("argv[%d]: %s", i, argv[i]);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种 print 代码删了


// Prints the normalized command-line arguments
// tb_trace_i("NEW:");
// tb_print_argv(new_argc, new_argv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删了

@duyanning duyanning closed this Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants