Skip to content

Commit 7b54d25

Browse files
committedFeb 5, 2025
util: Add dsp_getopt().
1 parent a80fcf8 commit 7b54d25

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed
 

‎util.c

+56
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,62 @@ char * isolate(char *s, char c)
350350
return s;
351351
}
352352

353+
/*
354+
* Slightly modified version of AT&T public domain getopt():
355+
* - Returns ':' for a missing option argument.
356+
* - Supports optional arguments (two colons).
357+
* - Allows optional arguments to be in the next argv element.
358+
* - Thread safe.
359+
*/
360+
#define IS_OPT(S) ((S)[0] == '-' && (S)[1] != '\0')
361+
int dsp_getopt(struct dsp_getopt_state *g, int argc, const char *const *argv, const char *opts)
362+
{
363+
int c;
364+
const char *cp;
365+
366+
if (g->sp == 1) {
367+
if (g->ind >= argc || !IS_OPT(argv[g->ind]))
368+
return -1;
369+
else if (strcmp(argv[g->ind], "--") == 0) {
370+
++g->ind;
371+
return -1;
372+
}
373+
}
374+
g->opt = c = argv[g->ind][g->sp];
375+
if (c == ':' || (cp = strchr(opts, c)) == NULL) {
376+
if (argv[g->ind][++g->sp] == '\0') {
377+
++g->ind;
378+
g->sp = 1;
379+
}
380+
g->opt = c;
381+
return '?';
382+
}
383+
if (cp[1] == ':') {
384+
if (argv[g->ind][g->sp + 1] != '\0')
385+
g->arg = &argv[g->ind++][g->sp + 1];
386+
else if (++g->ind >= argc) {
387+
g->sp = 1;
388+
if (cp[2] == ':') g->arg = NULL;
389+
else return ':';
390+
}
391+
else if (cp[2] == ':') {
392+
if (!IS_OPT(argv[g->ind]) && strcmp(argv[g->ind], "--") != 0)
393+
g->arg = argv[g->ind++];
394+
else g->arg = NULL;
395+
}
396+
else g->arg = argv[g->ind++];
397+
g->sp = 1;
398+
}
399+
else {
400+
if (argv[g->ind][++g->sp] == '\0') {
401+
++g->ind;
402+
g->sp = 1;
403+
}
404+
g->arg = NULL;
405+
}
406+
return c;
407+
}
408+
353409
#ifdef HAVE_FFTW3
354410
ssize_t next_fast_fftw_len(ssize_t min_len)
355411
{

‎util.h

+7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@
5555
#define IS_WHITESPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r')
5656
#define PM_RAND_MAX 0x7fffffff
5757

58+
struct dsp_getopt_state {
59+
const char *arg;
60+
int ind, opt, sp;
61+
};
62+
#define DSP_GETOPT_STATE_INITIALIZER ((struct dsp_getopt_state) { .ind = 1, .sp = 1 })
63+
5864
int check_endptr(const char *, const char *, const char *, const char *);
5965
double parse_freq(const char *, char **);
6066
ssize_t parse_len(const char *, int, char **);
@@ -67,6 +73,7 @@ int gen_argv_from_string(const char *, int *, char ***);
6773
char * get_file_contents(const char *);
6874
char * construct_full_path(const char *, const char *);
6975
char * isolate(char *, char);
76+
int dsp_getopt(struct dsp_getopt_state *, int, const char *const *, const char *);
7077
#ifdef HAVE_FFTW3
7178
ssize_t next_fast_fftw_len(ssize_t);
7279
void dsp_fftw_acquire(void);

0 commit comments

Comments
 (0)
Please sign in to comment.