1 // SPDX-License-Identifier: GPL-2.0
2 // main.c - an entry point for this program.
4 // Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 // Originally written as 'aplay', by Michael Beck and Jaroslav Kysela.
8 // Licensed under the terms of the GNU General Public License, version 2.
27 static void print_version(const char *const cmdname)
29 printf("%s: version %s\n", cmdname, SND_UTIL_VERSION_STR);
32 static void print_help(void)
37 static void decide_subcmd(int argc, char *const *argv, enum subcmds *subcmd)
39 static const char *const subcmds[] = {
40 [SUBCMD_TRANSFER] = "transfer",
41 [SUBCMD_LIST] = "list",
42 [SUBCMD_HELP] = "help",
43 [SUBCMD_VERSION] = "version",
46 const char *const name;
49 {"--list-devices", SUBCMD_LIST},
50 {"--list-pcms", SUBCMD_LIST},
51 {"--help", SUBCMD_HELP},
52 {"--version", SUBCMD_VERSION},
66 *subcmd = SUBCMD_HELP;
70 // sub-command system.
71 for (i = 0; i < ARRAY_SIZE(subcmds); ++i) {
72 if (!strcmp(argv[1], subcmds[i])) {
78 // Original command system. For long options.
79 for (i = 0; i < ARRAY_SIZE(long_opts); ++i) {
80 for (j = 0; j < argc; ++j) {
81 if (!strcmp(long_opts[i].name, argv[j])) {
82 *subcmd = long_opts[i].subcmd;
88 // Original command system. For short options.
89 for (i = 1; i < argc; ++i) {
90 // Pick up short options only.
91 if (argv[i][0] != '-' || argv[i][0] == '\0' ||
92 argv[i][1] == '-' || argv[i][1] == '\0')
94 for (pos = argv[i]; *pos != '\0'; ++pos) {
95 for (j = 0; j < ARRAY_SIZE(short_opts); ++j) {
96 if (*pos == short_opts[j].c) {
97 *subcmd = short_opts[j].subcmd;
104 *subcmd = SUBCMD_TRANSFER;
107 static bool decide_direction(int argc, char *const *argv,
108 snd_pcm_stream_t *direction)
110 static const struct {
111 const char *const name;
112 snd_pcm_stream_t direction;
114 {"--capture", SND_PCM_STREAM_CAPTURE},
115 {"--playback", SND_PCM_STREAM_PLAYBACK},
117 static const struct {
119 snd_pcm_stream_t direction;
121 {'C', SND_PCM_STREAM_CAPTURE},
122 {'P', SND_PCM_STREAM_PLAYBACK},
124 static const char *const aliases[] = {
125 [SND_PCM_STREAM_CAPTURE] = "arecord",
126 [SND_PCM_STREAM_PLAYBACK] = "aplay",
131 // Original command system. For long options.
132 for (i = 0; i < ARRAY_SIZE(long_opts); ++i) {
133 for (j = 0; j < argc; ++j) {
134 if (!strcmp(long_opts[i].name, argv[j])) {
135 *direction = long_opts[i].direction;
141 // Original command system. For short options.
142 for (i = 1; i < argc; ++i) {
143 // Pick up short options only.
144 if (argv[i][0] != '-' || argv[i][0] == '\0' ||
145 argv[i][1] == '-' || argv[i][1] == '\0')
147 for (pos = argv[i]; *pos != '\0'; ++pos) {
148 for (j = 0; j < ARRAY_SIZE(short_opts); ++j) {
149 if (*pos == short_opts[j].c) {
150 *direction = short_opts[j].direction;
157 // If not decided yet, judge according to command name.
158 for (i = 0; i < ARRAY_SIZE(aliases); ++i) {
159 for (pos = argv[0] + strlen(argv[0]); pos != argv[0]; --pos) {
160 if (strstr(pos, aliases[i]) != NULL) {
170 int main(int argc, char *const *argv)
172 snd_pcm_stream_t direction;
176 if (!decide_direction(argc, argv, &direction))
177 subcmd = SUBCMD_HELP;
179 decide_subcmd(argc, argv, &subcmd);
181 if (subcmd == SUBCMD_TRANSFER)
182 printf("execute 'transfer' subcmd.\n");
183 else if (subcmd == SUBCMD_LIST)
184 err = subcmd_list(argc, argv, direction);
185 else if (subcmd == SUBCMD_VERSION)
186 print_version(argv[0]);