为命令行实用程序寻找任何好的(和免费的)跨平台CLI解析库

时间:2010-06-21 09:32:20

标签: c++ parsing command-line

我目前正在开发一个CLI实用程序,我认为通过添加框架可以对其进行大量改进。

基本上,该实用程序围绕许多命令行语法和解析输出。目前,代码分散在各处,包含许多带有硬编码CLI参数的内部run()和readFromRunOutput()调用。

例如:

op=run("command -args");
while(readFromRunOutPUr(op))
{
// Process and take result from output
if(op=="result-one")
    dothis();
else if(op=="result-two")
    dothat();
}

我想创建一个通用的框架,其中的 以下内容通过XML文件从代码外部输入。     1)测试名称     2)命令行调用     3)成功所需的输出

所以假设一个简单的XML调用......

<Test name=FirstTest>   
<CLI="command -args">
<Success Output= "value" >
</Success>
</CLI>
</Test>

是。在上面的例子中有一些问题需要担心,但我想我已经给出了它的要点。基本上我想将所有不同的CLI调用移到代码之外,然后将它们提供给它们(带有成功和失败的标准)。由于很多其他原因,我不能使用任何脚本语言,如perl或python,并且必须使用C / C ++维护产品。

从我收集的要求是

Defined XML syntax
Parser for the above XML spec to memory
Get CLI -----> and invoke
Read Output and compare with the fed in values
(Preferably cross platform support)

这样的实现不仅可以标准化所有不同的单个函数调用,还可以在不进行任何代码更改的情况下轻松扩展。

现在我的问题是,是否有任何现成的免费库(用于C ++)已经提供了类似或基本的模板框架,我可以在其上扩展。优选第一手经验。还有其他指导吗?

4 个答案:

答案 0 :(得分:1)

好的,对你真正的问题:

首先,您将需要一个正确的XML解析器(仅使用Qt的XML和XERXES,这可能是您的用例,我不能真正推荐一个,但libxml2似乎被广泛使用)用于您的输入。 如果我理解正确,您只需将CLI标记的内容传递给命令行,因此不需要解析。你真正的问题似乎是Success Output,对吧?

如果是这样,你必须回答的第一个问题是这个值意味着什么?如果字符串在输出中的某个位置就足够了吗?上下文是否相关?如果是这样,怎么编码呢?常用表达?或者更确切地说,XML配置中的不同节点如<contains>,...

根据您需要找到不同解析器的答案。你最有可能使用正则表达式引擎(例如Boost :: regex)。

所有这一切都说,看起来这应该是某种测试框架,你看过可用的替代方案,想到CMake的CTest,可能有很多其他的。

答案 1 :(得分:0)

我不明白你究竟在寻找什么,但看看Boost Program Options。它可以处理大多数开箱即用的CL解析,并且可以在其余部分轻松扩展。

答案 2 :(得分:0)

关于我的确切需要..可能是一个用例会帮助... 让我们说我的工具需要检查“dir”的输出为“file.txt”。我需要编写一个函数来运行命令+解析输出+搜索输入值。现在让我们说另外需要检查“dir”的输出,但这次检查“卷序列号”的值。类似的需要但不一样。 “dir”相同,这次将文件数作为输出。现在我可以坐下来写下并覆盖所有的风景。或者重用一个专用于不同类型命令行解析的现有库。

我希望的第二个用例是将成品交给其他用户(基本上可以重复使用)。因此,如果用户有一个我没有涉及的测试用例,他可以通过已发布的模式添加它(“Dir”..目标值。)

所以基本上我正在寻找一个专用于CLI解析/处理的C / C ++友好库,它具有灵活的输入框架。另一种方法是从头开始自己做。

答案 3 :(得分:0)

我为此使用Glib。他们有很好的方法。

// Declare some file-scope variables
static gint repeats = 2;
static gint max_size = 8;
static gboolean verbose = FALSE;
static gboolean beep = FALSE;
static gboolean rand = FALSE;

// Here you define the options you want
static GOptionEntry entries[] =
{
  { "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
  { "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
  { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
  { "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL },
  { "rand", 0, 0, G_OPTION_ARG_NONE, &rand, "Randomize the data", NULL },
  { NULL }
};

int main (int argc, char *argv[]){

 // You need this for correctly initiate the parser
  GError *error = NULL;
  GOptionContext *context;

  context = g_option_context_new ("- test tree model performance");
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
  g_option_context_add_group (context, gtk_get_option_group (TRUE));
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_print ("option parsing failed: %s\n", error->message);
      exit (1);
    }

 // Then comes your code
  /* ... */

}

http://developer.gnome.org/glib/2.28/glib-Commandline-option-parser.html了解详情。