summaryrefslogtreecommitdiff
path: root/alsactl
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2021-03-10 20:06:24 +0100
committerJaroslav Kysela <perex@perex.cz>2021-03-11 09:23:33 +0100
commiteefc2c61cfda4325373e1fa2d3be1642c92eee83 (patch)
tree79f0a9df723d0b0f2b4f2984f24b94ff94d9cdd3 /alsactl
parent9a2115b5ccb53b0224bdc3bc965c1e6de7e82a2d (diff)
downloadalsa-utils-eefc2c61cfda4325373e1fa2d3be1642c92eee83.tar.gz
alsactl: use card iterator functions for all card loops
Take the card iterator idea from the monitor code and use it for all card loops. It reduces the code duplications and makes things easy to review. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'alsactl')
-rw-r--r--alsactl/alsactl.h13
-rw-r--r--alsactl/clean.c47
-rw-r--r--alsactl/init_parse.c74
-rw-r--r--alsactl/monitor.c28
-rw-r--r--alsactl/state.c155
-rw-r--r--alsactl/utils.c51
6 files changed, 131 insertions, 237 deletions
diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h
index 0e24d60..ca723e3 100644
--- a/alsactl/alsactl.h
+++ b/alsactl/alsactl.h
@@ -1,3 +1,4 @@
+#include <stdbool.h>
#include <alsa/asoundlib.h>
extern int debugflag;
@@ -9,6 +10,13 @@ extern char *command;
extern char *statefile;
extern char *lockfile;
+struct snd_card_iterator {
+ int card;
+ char name[16];
+ bool single;
+ bool first;
+};
+
void info_(const char *fcn, long line, const char *fmt, ...);
void error_(const char *fcn, long line, const char *fmt, ...);
void cerror_(const char *fcn, long line, int cond, const char *fmt, ...);
@@ -32,6 +40,11 @@ void error_handler(const char *file, int line, const char *function, int err, co
#define FLAG_UCM_BOOT (1<<2)
#define FLAG_UCM_DEFAULTS (1<<3)
+void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno);
+int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname);
+const char *snd_card_iterator_next(struct snd_card_iterator *iter);
+int snd_card_iterator_error(struct snd_card_iterator *iter);
+
int load_configuration(const char *file, snd_config_t **top, int *open_failed);
int init(const char *file, int flags, const char *cardname);
int init_ucm(int flags, int cardno);
diff --git a/alsactl/clean.c b/alsactl/clean.c
index 4808225..6dfc6d3 100644
--- a/alsactl/clean.c
+++ b/alsactl/clean.c
@@ -182,46 +182,15 @@ fin_err:
int clean(const char *cardname, char *const *extra_args)
{
+ struct snd_card_iterator iter;
int err;
- if (!cardname) {
- int card, first = 1;
-
- card = -1;
- /* find each installed soundcards */
- while (1) {
- if (snd_card_next(&card) < 0)
- break;
- if (card < 0) {
- if (first) {
- if (ignore_nocards) {
- err = 0;
- goto out;
- } else {
- error("No soundcards found...");
- err = -ENODEV;
- goto out;
- }
- }
- break;
- }
- first = 0;
- if ((err = clean_controls(card, extra_args)))
- goto out;
- }
- } else {
- int cardno;
-
- cardno = snd_card_get_index(cardname);
- if (cardno < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = cardno;
- goto out;
- }
- if ((err = clean_controls(cardno, extra_args))) {
- goto out;
- }
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ return err;
+ while (snd_card_iterator_next(&iter)) {
+ if ((err = clean_controls(iter.card, extra_args)))
+ return err;
}
-out:
- return err;
+ return snd_card_iterator_error(&iter);
}
diff --git a/alsactl/init_parse.c b/alsactl/init_parse.c
index 4034b4d..ab2c906 100644
--- a/alsactl/init_parse.c
+++ b/alsactl/init_parse.c
@@ -1746,63 +1746,33 @@ static int parse(struct space *space, const char *filename)
int init(const char *filename, int flags, const char *cardname)
{
struct space *space;
- int err = 0, lasterr = 0, card, first;
+ struct snd_card_iterator iter;
+ int err = 0, lasterr = 0;
sysfs_init();
- if (!cardname) {
- first = 1;
- card = -1;
- while (1) {
- if (snd_card_next(&card) < 0)
- break;
- if (card < 0) {
- if (first) {
- if (ignore_nocards)
- return 0;
- error("No soundcards found...");
- return -ENODEV;
- }
- break;
- }
- first = 0;
- err = init_ucm(flags, card);
- if (err == 0)
- continue;
- err = init_space(&space, card);
- if (err == 0) {
- space->rootdir = new_root_dir(filename);
- if (space->rootdir != NULL)
- err = parse(space, filename);
- if (err <= -99) { /* non-fatal errors */
- if (lasterr == 0)
- lasterr = err;
- err = 0;
- }
- free_space(space);
- }
- if (err < 0)
- break;
- }
- err = lasterr;
- } else {
- card = snd_card_get_index(cardname);
- if (card < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- goto error;
- }
- err = init_ucm(flags, card);
+ err = snd_card_iterator_sinit(&iter, cardname);
+ while (snd_card_iterator_next(&iter)) {
+ err = init_ucm(flags, iter.card);
if (err == 0)
- return 0;
- memset(&space, 0, sizeof(space));
- err = init_space(&space, card);
- if (err == 0) {
- space->rootdir = new_root_dir(filename);
- if (space->rootdir != NULL)
- err = parse(space, filename);
- free_space(space);
+ continue;
+ err = init_space(&space, iter.card);
+ if (err != 0)
+ continue;
+ space->rootdir = new_root_dir(filename);
+ if (space->rootdir != NULL) {
+ err = parse(space, filename);
+ if (!cardname && err <= -99) { /* non-fatal errors */
+ if (lasterr == 0)
+ lasterr = err;
+ err = 0;
+ }
}
+ free_space(space);
+ if (err < 0)
+ goto out;
}
- error:
+ err = lasterr ? lasterr : snd_card_iterator_error(&iter);
+out:
sysfs_cleanup();
return err;
}
diff --git a/alsactl/monitor.c b/alsactl/monitor.c
index fa6cd85..4c02557 100644
--- a/alsactl/monitor.c
+++ b/alsactl/monitor.c
@@ -28,11 +28,12 @@
#include <time.h>
#include <signal.h>
#include <sys/signalfd.h>
-#include <alsa/asoundlib.h>
#include <stddef.h>
#include "list.h"
+#include "alsactl.h"
+
struct src_entry {
snd_ctl_t *handle;
char *name;
@@ -40,29 +41,6 @@ struct src_entry {
struct list_head list;
};
-struct snd_card_iterator {
- int card;
- char name[16];
-};
-
-void snd_card_iterator_init(struct snd_card_iterator *iter)
-{
- iter->card = -1;
- memset(iter->name, 0, sizeof(iter->name));
-}
-
-static const char *snd_card_iterator_next(struct snd_card_iterator *iter)
-{
- if (snd_card_next(&iter->card) < 0)
- return NULL;
- if (iter->card < 0)
- return NULL;
-
- snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card);
-
- return (const char *)iter->name;
-}
-
static void remove_source_entry(struct src_entry *entry)
{
list_del(&entry->list);
@@ -159,7 +137,7 @@ static int prepare_source_entry(struct list_head *srcs, const char *name)
struct snd_card_iterator iter;
const char *cardname;
- snd_card_iterator_init(&iter);
+ snd_card_iterator_init(&iter, -1);
while ((cardname = snd_card_iterator_next(&iter))) {
if (seek_entry_by_name(srcs, cardname))
continue;
diff --git a/alsactl/state.c b/alsactl/state.c
index e39e878..0612970 100644
--- a/alsactl/state.c
+++ b/alsactl/state.c
@@ -1544,6 +1544,7 @@ int save_state(const char *file, const char *cardname)
int stdio;
char *nfile = NULL;
int lock_fd = -EINVAL;
+ struct snd_card_iterator iter;
err = snd_config_top(&config);
if (err < 0) {
@@ -1577,45 +1578,18 @@ int save_state(const char *file, const char *cardname)
#endif
}
- if (!cardname) {
- int card, first = 1;
-
- card = -1;
- /* find each installed soundcards */
- while (1) {
- if (snd_card_next(&card) < 0)
- break;
- if (card < 0) {
- if (first) {
- if (ignore_nocards) {
- err = 0;
- goto out;
- } else {
- error("No soundcards found...");
- err = -ENODEV;
- goto out;
- }
- }
- break;
- }
- first = 0;
- if ((err = get_controls(card, config)))
- goto out;
- }
- } else {
- int cardno;
-
- cardno = snd_card_get_index(cardname);
- if (cardno < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = cardno;
- goto out;
- }
- if ((err = get_controls(cardno, config))) {
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ goto out;
+ while (snd_card_iterator_next(&iter)) {
+ if ((err = get_controls(iter.card, config)))
goto out;
- }
}
-
+ if (iter.first) {
+ err = snd_card_iterator_error(&iter);
+ goto out;
+ }
+
if (stdio) {
err = snd_output_stdio_attach(&out, stdout, 0);
} else {
@@ -1648,119 +1622,58 @@ int load_state(const char *file, const char *initfile, int initflags,
const char *cardname, int do_init)
{
int err, finalerr = 0, open_failed;
+ struct snd_card_iterator iter;
snd_config_t *config;
+ const char *cardname1;
err = load_configuration(file, &config, &open_failed);
if (err < 0 && !open_failed)
return err;
if (open_failed) {
- int card, first = 1;
- char cardname1[16];
-
error("Cannot open %s for reading: %s", file, snd_strerror(err));
finalerr = err;
- if (cardname) {
- card = snd_card_get_index(cardname);
- if (card < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = -ENODEV;
- goto out;
- }
- goto single;
- } else {
- card = -1;
- }
- /* find each installed soundcards */
- while (!cardname) {
- if (snd_card_next(&card) < 0)
- break;
- if (card < 0)
- break;
-single:
- first = 0;
+
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ return err;
+ while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
if (!do_init)
break;
- sprintf(cardname1, "%i", card);
err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
if (err < 0) {
finalerr = err;
- initfailed(card, "init", err);
+ initfailed(iter.card, "init", err);
}
- initfailed(card, "restore", -ENOENT);
+ initfailed(iter.card, "restore", -ENOENT);
}
- if (first)
- finalerr = 0; /* no cards, no error code */
err = finalerr;
+ if (iter.first)
+ err = 0; /* no cards, no error code */
goto out;
}
- if (!cardname) {
- int card, first = 1;
- char cardname1[16];
-
- card = -1;
- /* find each installed soundcards */
- while (1) {
- if (snd_card_next(&card) < 0)
- break;
- if (card < 0) {
- if (first) {
- if (ignore_nocards) {
- err = 0;
- goto out;
- } else {
- error("No soundcards found...");
- err = -ENODEV;
- goto out;
- }
- }
- break;
- }
- first = 0;
- /* error is ignored */
- init_ucm(initflags | FLAG_UCM_FBOOT, card);
- /* do a check if controls matches state file */
- if (do_init && set_controls(card, config, 0)) {
- sprintf(cardname1, "%i", card);
- err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
- if (err < 0) {
- initfailed(card, "init", err);
- finalerr = err;
- }
- }
- if ((err = set_controls(card, config, 1))) {
- if (!force_restore)
- finalerr = err;
- initfailed(card, "restore", err);
- }
- }
- } else {
- int cardno;
-
- cardno = snd_card_get_index(cardname);
- if (cardno < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = -ENODEV;
- goto out;
- }
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ goto out;
+ while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
/* error is ignored */
- init_ucm(initflags | FLAG_UCM_FBOOT, cardno);
+ init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
/* do a check if controls matches state file */
- if (do_init && set_controls(cardno, config, 0)) {
- err = init(initfile, initflags | FLAG_UCM_BOOT, cardname);
+ if (do_init && set_controls(iter.card, config, 0)) {
+ err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
if (err < 0) {
- initfailed(cardno, "init", err);
+ initfailed(iter.card, "init", err);
finalerr = err;
}
}
- if ((err = set_controls(cardno, config, 1))) {
- initfailed(cardno, "restore", err);
+ if ((err = set_controls(iter.card, config, 1))) {
if (!force_restore)
- goto out;
+ finalerr = err;
+ initfailed(iter.card, "restore", err);
}
}
- err = finalerr;
+ err = finalerr ? finalerr : snd_card_iterator_error(&iter);
out:
snd_config_delete(config);
snd_config_update_free_global();
diff --git a/alsactl/utils.c b/alsactl/utils.c
index ede7319..d0b1ac6 100644
--- a/alsactl/utils.c
+++ b/alsactl/utils.c
@@ -233,3 +233,54 @@ out:
return 0;
}
}
+
+void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno)
+{
+ iter->card = cardno;
+ iter->single = cardno >= 0;
+ iter->first = true;
+ iter->name[0] = '\0';
+}
+
+int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname)
+{
+ int cardno = -1;
+
+ if (cardname) {
+ cardno = snd_card_get_index(cardname);
+ if (cardno < 0) {
+ error("Cannot find soundcard '%s'...", cardname);
+ return cardno;
+ }
+ }
+ snd_card_iterator_init(iter, cardno);
+ return 0;
+}
+
+const char *snd_card_iterator_next(struct snd_card_iterator *iter)
+{
+ if (iter->single) {
+ if (iter->first) {
+ iter->first = false;
+ goto retval;
+ }
+ return NULL;
+ }
+ if (snd_card_next(&iter->card) < 0) {
+ if (!ignore_nocards && iter->first)
+ error("No soundcards found...");
+ return NULL;
+ }
+ iter->first = false;
+ if (iter->card < 0)
+ return NULL;
+retval:
+ snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card);
+
+ return (const char *)iter->name;
+}
+
+int snd_card_iterator_error(struct snd_card_iterator *iter)
+{
+ return iter->first ? (ignore_nocards ? 0 : -ENODEV) : 0;
+}