Handle streams separately in tree_add_track()
[cmus.git] / prog.c
blob1637522cfd1910b25eb796b124834ddde1f826e5
1 /*
2 * Copyright 2005 Timo Hirvonen
3 */
5 #include "prog.h"
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdarg.h>
11 #include <errno.h>
13 char *program_name = NULL;
15 void warn(const char *format, ...)
17 va_list ap;
19 fprintf(stderr, "%s: ", program_name);
20 va_start(ap, format);
21 vfprintf(stderr, format, ap);
22 va_end(ap);
25 void warn_errno(const char *format, ...)
27 int e = errno;
28 va_list ap;
30 fprintf(stderr, "%s: ", program_name);
31 va_start(ap, format);
32 vfprintf(stderr, format, ap);
33 va_end(ap);
34 fprintf(stderr, ": %s\n", strerror(e));
37 void __NORETURN die(const char *format, ...)
39 va_list ap;
41 fprintf(stderr, "%s: ", program_name);
42 va_start(ap, format);
43 vfprintf(stderr, format, ap);
44 va_end(ap);
45 exit(1);
48 void __NORETURN die_errno(const char *format, ...)
50 int e = errno;
51 va_list ap;
53 fprintf(stderr, "%s: ", program_name);
54 va_start(ap, format);
55 vfprintf(stderr, format, ap);
56 va_end(ap);
57 fprintf(stderr, ": %s\n", strerror(e));
58 exit(1);
61 static int short_option(int ch, const struct option *options)
63 int i;
65 for (i = 0; ; i++) {
66 if (!options[i].short_opt) {
67 if (!options[i].long_opt)
68 die("unrecognized option `-%c'\n", ch);
69 continue;
71 if (options[i].short_opt != ch)
72 continue;
73 return i;
77 static int long_option(const char *opt, const struct option *options)
79 int len, i, idx, num;
81 len = strlen(opt);
82 idx = -1;
83 num = 0;
84 for (i = 0; options[i].short_opt || options[i].long_opt; i++) {
85 if (options[i].long_opt && strncmp(opt, options[i].long_opt, len) == 0) {
86 idx = i;
87 num++;
88 if (options[i].long_opt[len] == 0) {
89 /* exact */
90 num = 1;
91 break;
95 if (num > 1)
96 die("option `--%s' is ambiguous\n", opt);
97 if (num == 0)
98 die("unrecognized option `--%s'\n", opt);
99 return idx;
102 int get_option(char **argvp[], const struct option *options, char **arg)
104 char **argv = *argvp;
105 const char *opt = *argv;
106 int i;
108 *arg = NULL;
109 if (opt == NULL || opt[0] != '-' || opt[1] == 0)
110 return -1;
112 if (opt[1] == '-') {
113 if (opt[2] == 0) {
114 /* '--' => no more options */
115 *argvp = argv + 1;
116 return -1;
118 i = long_option(opt + 2, options);
119 } else if (opt[2]) {
120 return -1;
121 } else {
122 i = short_option(opt[1], options);
124 argv++;
125 if (options[i].has_arg) {
126 if (*argv == NULL)
127 die("option `%s' requires an argument\n", opt);
128 *arg = *argv++;
130 *argvp = argv;
131 return i;