如何基于命令行参数运行程序的不同“模式"? [英] How to run different 'modes' of a program based on command line parameters?

查看:83
本文介绍了如何基于命令行参数运行程序的不同“模式"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Openssl的源代码,以发现程序员如何使基于命令行参数运行不同的应用程序成为可能.例如:我可以运行具有自己选项的openssl speed,也可以运行具有其自己选项的openssl s_server,依此类推.在许多操作系统上,这一切都像魅力一样.此外,Openssl还有一些我称为命令行建议"的东西,当我按制表键时,它会建议可用的选项.

I'm looking into Openssl's source code to find out how the programmers made it possible to run different applications based on command line arguments. For instance: I can run openssl speed, which has its own options, I can run openssl s_server which has its own options as well, and so on. It all works like a charm on many operating systems. Besides, Openssl have something which I call 'command line suggestions' where it suggests available options when I press the tabulator key.

我正在研究源代码,但是不知道如何在我的应用程序中实现类似的东西.有什么想法吗?

I'm looking into source code but have any clue how to implement something similar in my application. Any ideas?

推荐答案

程序员如何基于命令行参数运行不同的应用程序成为可能.

how the programmers made it possible to run different applications based on command line arguments.

这些在OpenSSL中称为子命令.它们包括s_cients_serverdigestencdecx509speed等.

Those are called subcommands in OpenSSL. They include s_cient, s_server, digest, enc, dec, x509, speed, etc.

有什么想法吗?

Any ideas?

OpenSSL为openssl命令和所有子命令提供一个main.子命令中的main被包装在宏中,因此,如果 not 不能构建openssl命令,则该子命令可以成为其自己的独立程序.

OpenSSL provides a a main for the openssl command and all the subcommands. The main in the subcommand is wrapped in a macro so that if not building openssl command, then the subcommand can become its own stand-alone program.

这是该宏的用法.所有子命令都可以执行此操作:

Here's what the use of the macro look like. All of the subcommands do this:

int MAIN(int, char **);

int MAIN(int argc, char **argv)
    {
        ...
    }

OpenSSL知道何时将所有子命令与openssl命令一起使用,并且它定义MONOLITH以在子命令中关闭" mains.

OpenSSL knows when its including all the subcommands with the openssl command, and it defines MONOLITH to switch "off" the mains in the subcommands.

并且来自apps.h:

#ifndef MONOLITH

#define MAIN(a,v)   main(a,v)

#ifndef NON_MAIN
CONF *config=NULL;
BIO *bio_err=NULL;
#else
extern CONF *config;
extern BIO *bio_err;
#endif

#else

#define MAIN(a,v)   PROG(a,v)
extern CONF *config;
extern char *default_config_file;
extern BIO *bio_err;

#endif

如果是独立构建的子命令,则还需要构建apps.c并链接到apps.o,因为它对它们来说是通用的.

If you build the subcommand stand-alone, then you will also need to build apps.c and link to apps.o because its common to them.

如果我没记错的话,当使用预处理器魔术来定义MONOLITH时,PROG会展开为prog_xxx之类的内容,其中xxx是所讨论的子命令.因此,它们看起来像一堆函数:prog_s_cientprog_s_serverprog_digest等.

If I recall correctly, PROG unrolls to something like prog_xxx when MONOLITH is defined using preprocessor magic, where xxx is the subcommand in question. So they just look like a bunch of functions: prog_s_cient, prog_s_server, prog_digest, etc.

$ cd apps
$ grep -R MAIN *
app_rand.c:#define NON_MAIN
app_rand.c:#undef NON_MAIN
apps.c:#define NON_MAIN
apps.c:#undef NON_MAIN
apps.h:#define MAIN(a,v)    main(a,v)
apps.h:#ifndef NON_MAIN
apps.h:#define MAIN(a,v)    PROG(a,v)
asn1pars.c:int MAIN(int, char **);
asn1pars.c:int MAIN(int argc, char **argv)
ca.c:int MAIN(int, char **);
ca.c:int MAIN(int argc, char **argv)
ciphers.c:int MAIN(int, char **);
ciphers.c:int MAIN(int argc, char **argv)
cms.c:int MAIN(int, char **);
cms.c:int MAIN(int argc, char **argv)
crl.c:int MAIN(int, char **);
crl.c:int MAIN(int argc, char **argv)
crl2p7.c:int MAIN(int, char **);
crl2p7.c:int MAIN(int argc, char **argv)
dgst.c:int MAIN(int, char **);
dgst.c:int MAIN(int argc, char **argv)
dh.c:int MAIN(int, char **);
dh.c:int MAIN(int argc, char **argv)
dhparam.c:int MAIN(int, char **);
dhparam.c:int MAIN(int argc, char **argv)
dsa.c:int MAIN(int, char **);
dsa.c:int MAIN(int argc, char **argv)
dsaparam.c:int MAIN(int, char **);
dsaparam.c:int MAIN(int argc, char **argv)
ec.c:int MAIN(int, char **);
ec.c:int MAIN(int argc, char **argv)
ecparam.c:int MAIN(int, char **);
ecparam.c:int MAIN(int argc, char **argv)
enc.c:int MAIN(int, char **);
enc.c:int MAIN(int argc, char **argv)
engine.c:int MAIN(int, char **);
engine.c:int MAIN(int argc, char **argv)
errstr.c:int MAIN(int, char **);
errstr.c:int MAIN(int argc, char **argv)
gendh.c:int MAIN(int, char **);
gendh.c:int MAIN(int argc, char **argv)
gendsa.c:int MAIN(int, char **);
gendsa.c:int MAIN(int argc, char **argv)
genpkey.c:int MAIN(int, char **);
genpkey.c:int MAIN(int argc, char **argv)
genrsa.c:int MAIN(int, char **);
genrsa.c:int MAIN(int argc, char **argv)
nseq.c:int MAIN(int, char **);
nseq.c:int MAIN(int argc, char **argv)
ocsp.c:int MAIN(int, char **);
ocsp.c:int MAIN(int argc, char **argv)
passwd.c:int MAIN(int, char **);
passwd.c:int MAIN(int argc, char **argv)
passwd.c:int MAIN(int argc, char **argv)
pkcs12.c:int MAIN(int, char **);
pkcs12.c:int MAIN(int argc, char **argv)
pkcs7.c:int MAIN(int, char **);
pkcs7.c:int MAIN(int argc, char **argv)
pkcs8.c:int MAIN(int, char **);
pkcs8.c:int MAIN(int argc, char **argv)
pkey.c:int MAIN(int, char **);
pkey.c:int MAIN(int argc, char **argv)
pkeyparam.c:int MAIN(int, char **);
pkeyparam.c:int MAIN(int argc, char **argv)
pkeyutl.c:int MAIN(int argc, char **);
pkeyutl.c:int MAIN(int argc, char **argv)
prime.c:int MAIN(int, char **);
prime.c:int MAIN(int argc, char **argv)
rand.c:int MAIN(int, char **);
rand.c:int MAIN(int argc, char **argv)
req.c:int MAIN(int, char **);
req.c:int MAIN(int argc, char **argv)
rsa.c:int MAIN(int, char **);
rsa.c:int MAIN(int argc, char **argv)
rsautl.c:int MAIN(int argc, char **);
rsautl.c:int MAIN(int argc, char **argv)
s_cb.c:#define NON_MAIN
s_cb.c:#undef NON_MAIN
s_client.c:int MAIN(int, char **);
s_client.c:int MAIN(int argc, char **argv)
s_server.c:int MAIN(int, char **);
s_server.c:int MAIN(int argc, char *argv[])
s_socket.c:#define NON_MAIN
s_socket.c:#undef NON_MAIN
s_time.c: * MAIN - main processing area for client
s_time.c:int MAIN(int, char **);
s_time.c:int MAIN(int argc, char **argv)
sess_id.c:int MAIN(int, char **);
sess_id.c:int MAIN(int argc, char **argv)
smime.c:int MAIN(int, char **);
smime.c:int MAIN(int argc, char **argv)
speed.c:int MAIN(int, char **);
speed.c:int MAIN(int argc, char **argv)
spkac.c:int MAIN(int, char **);
spkac.c:int MAIN(int argc, char **argv)
srp.c:int MAIN(int, char **);
srp.c:int MAIN(int argc, char **argv)
ts.c:int MAIN(int, char **);
ts.c:int MAIN(int argc, char **argv)
verify.c:int MAIN(int, char **);
verify.c:int MAIN(int argc, char **argv)
version.c:int MAIN(int, char **);
version.c:int MAIN(int argc, char **argv)
x509.c:int MAIN(int, char **);
x509.c:int MAIN(int argc, char **argv)

这篇关于如何基于命令行参数运行程序的不同“模式"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆