浏览代码

Try to use the clipp library for argument parsing.

wip/core-clipp
Sam Hocevar 4 年前
父节点
当前提交
b5a498ad14
共有 4 个文件被更改,包括 5 次插入174 次删除
  1. +3
    -0
      .gitmodules
  2. +1
    -0
      include/lol/3rdparty/clipp
  3. +1
    -1
      include/lol/getopt
  4. +0
    -173
      include/lol/private/sys/getopt.h

+ 3
- 0
.gitmodules 查看文件

@@ -10,3 +10,6 @@
path = include/lol/3rdparty/portable-file-dialogs
url = ../../samhocevar/portable-file-dialogs.git
branch = master
[submodule "clipp"]
path = include/lol/3rdparty/clipp
url = ../../muellan/clipp.git

+ 1
- 0
include/lol/3rdparty/clipp

@@ -0,0 +1 @@
Subproject commit 2c32b2f1f7cc530b1ec1f62c92f698643bb368db

+ 1
- 1
include/lol/getopt 查看文件

@@ -13,6 +13,6 @@
#pragma once

#include "private/push_macros.h"
#include "private/sys/getopt.h"
#include "3rdparty/clipp/include/clipp.h"
#include "private/pop_macros.h"


+ 0
- 173
include/lol/private/sys/getopt.h 查看文件

@@ -1,173 +0,0 @@
//
// Lol Engine
//
// Copyright © 2002—2016 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The getopt functions
// --------------------
//

#include <vector>
#include <string>
#include <cstring>

namespace lol
{

class getopt
{
public:
getopt(int argc, char ** argv)
: m_argc(argc),
m_argv(argv)
{
}

getopt(int argc, char * const * argv)
: m_argc(argc),
m_argv(argv)
{
}

void add_opt(int short_opt, char const *long_opt, bool has_arg)
{
optdesc o { long_opt, has_arg, nullptr, short_opt };
m_opts.push_back(o);

/* “The standards require that the argument [to isalnum()] is either
* EOF or a value that is representable in the type unsigned char.” */
if ((int)(unsigned char)short_opt == short_opt && isalnum(short_opt))
{
m_optstring += (char)short_opt;
if (has_arg)
m_optstring += ':';
}
}

int parse()
{
/* XXX: this getopt_long implementation should not be trusted for other
* applications without any serious peer reviewing. It “just works” with
* zzuf and a few libcaca programs but may fail miserably in other
* programs. */
char **argv = (char **)(uintptr_t)m_argv;
char *flag;

if (this->index >= m_argc)
return -1;

flag = argv[this->index];

if (flag[0] == '-' && flag[1] != '-')
{
char const *tmp;
int ret = flag[1];

if (ret == '\0')
return -1;

tmp = strchr(m_optstring.c_str(), ret);
if (!tmp || ret == ':')
return '?';

++this->index;
if (tmp[1] == ':')
{
if (flag[2] != '\0')
this->arg = flag + 2;
else
{
if (this->index >= m_argc)
goto too_few;
this->arg = argv[this->index++];
}
return ret;
}

if (flag[2] != '\0')
{
flag[1] = '-';
--this->index;
++argv[this->index];
}

return ret;
}

if (flag[0] == '-' && flag[1] == '-')
{
if (flag[2] == '\0')
return -1;

for (int i = 0; m_opts[i].name; ++i)
{
size_t l = strlen(m_opts[i].name);

if (strncmp(flag + 2, m_opts[i].name, l))
continue;

switch (flag[2 + l])
{
case '=':
if (!m_opts[i].has_arg)
goto bad_opt;
++this->index;
this->arg = flag + 2 + l + 1;
return m_opts[i].val;
case '\0':
++this->index;
if (m_opts[i].has_arg)
{
if (this->index >= m_argc)
goto too_few;
this->arg = argv[this->index++];
}
return m_opts[i].val;
default:
break;
}
}
bad_opt:
fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
return '?';

too_few:
fprintf(stderr, "%s: option `%s' requires an argument\n",
argv[0], flag);
return '?';
}

return -1;
}

int index = 1;
char *arg = nullptr;

private:
struct optdesc
{
char const *name;
int has_arg;
int *flag;
int val;
};

int m_argc;
char * const *m_argv;

std::string m_optstring;
std::vector<optdesc> m_opts;
};

} // namespace lol


正在加载...
取消
保存