source: roaraudio/roarclients/roar-config.c @ 5908:66940b2023ee

Last change on this file since 5908:66940b2023ee was 5828:d981716ace28, checked in by phi, 11 years ago

added a way to list all known paths

File size: 9.8 KB
Line 
1//roar-config.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include <roaraudio.h>
27
28static const struct {
29 const char * name;
30 const char * cflags;
31 const char * libs;
32} flags[] = {
33 // native/own libs:
34 {"roar",      ROAR_CFLAGS, ROAR_LIBS        }, // NOTE: libroar *MUST* be the first entry
35 {"roardsp",   ROAR_CFLAGS, ROAR_LIBS_DSP    },
36 {"roarmidi",  ROAR_CFLAGS, ROAR_LIBS_MIDI   },
37 {"roarlight", ROAR_CFLAGS, ROAR_LIBS_LIGHT  },
38 {"roareio",   ROAR_CFLAGS, ROAR_LIBS_EIO    },
39 // comp libs:
40 {"roaresd",   ROAR_CFLAGS, ROAR_LIBS_C_ESD  },
41 {"esd",       ROAR_CFLAGS, ROAR_LIBS_C_ESD  },
42 {"roarartsc", ROAR_CFLAGS, ROAR_LIBS_C_ARTSC},
43 {"artsc",     ROAR_CFLAGS, ROAR_LIBS_C_ARTSC},
44 {"roarpulse", ROAR_CFLAGS, ROAR_LIBS_C_PULSE},
45 {"pulse",     ROAR_CFLAGS, ROAR_LIBS_C_PULSE},
46 {"roarpulse-simple", ROAR_CFLAGS, ROAR_LIBS_C_PULSE_SIMPLE},
47 {"pulse-simple",     ROAR_CFLAGS, ROAR_LIBS_C_PULSE_SIMPLE},
48 {"roarsndio", ROAR_CFLAGS, ROAR_LIBS_C_SNDIO},
49 {"sndio",     ROAR_CFLAGS, ROAR_LIBS_C_SNDIO},
50 {"roaryiff",  ROAR_CFLAGS, ROAR_LIBS_C_YIFF },
51 {"Y2",        ROAR_CFLAGS, ROAR_LIBS_C_YIFF },
52 {NULL, NULL, NULL}
53}, * flags_ptr = NULL;
54
55struct version {
56 int major, minor, revision;
57};
58
59static struct version parse_version(const char * version) {
60 struct version ret = {-1, -1, -1};
61 char * next;
62
63 if ( !strcasecmp(version, "current") )
64  version = ROAR_VERSION_COMMON;
65
66 ret.major    = strtoll(version, &next, 0);
67 ret.minor    = strtoll(next+1, &next, 0);
68 ret.revision = strtoll(next+1, &next, 0);
69
70 return ret;
71}
72
73static int compare_versions_eq(struct version a, struct version b) {
74 return a.major == b.major && a.minor == b.minor && a.revision == b.revision;
75}
76
77static int compare_versions_gt(struct version a, struct version b) {
78 if ( a.major > b.major )
79  return 1;
80 if ( a.minor > b.minor )
81  return 1;
82 if ( a.revision > b.revision )
83  return 1;
84 return 0;
85}
86
87static int compare_versions_ge(struct version a, struct version b) {
88 return compare_versions_gt(a, b) || compare_versions_eq(a, b);
89}
90
91static int compare_versions_lt(struct version a, struct version b) {
92 return compare_versions_gt(b, a);
93}
94
95static int compare_versions_le(struct version a, struct version b) {
96 return compare_versions_lt(a, b) || compare_versions_eq(a, b);
97}
98
99static const struct {
100 const char * op;
101 int neg;
102 int (*func)(struct version a, struct version b);
103} compare_versions_funcs[] = {
104 {"eq", 0, compare_versions_eq},
105 {"ne", 1, compare_versions_eq},
106 {"gt", 0, compare_versions_gt},
107 {"ge", 0, compare_versions_ge},
108 {"lt", 0, compare_versions_lt},
109 {"le", 0, compare_versions_le}
110};
111
112static int compare_versions(const char * a, const char * op, const char * b) {
113 struct version va = parse_version(a);
114 struct version vb = parse_version(b);
115 size_t i;
116 int ret;
117
118 ROAR_DBG("compare_versions(a='%s', op='%s', b='%s'): {%i, %i, %i} <%s> {%i, %i, %i}\n", a, op, b, va.major, va.minor, va.revision, op, vb.major, vb.minor, vb.revision);
119
120 for (i = 0; i < (sizeof(compare_versions_funcs)/sizeof(*compare_versions_funcs)); i++) {
121  if ( !strcasecmp(compare_versions_funcs[i].op, op) ) {
122   ret = compare_versions_funcs[i].func(va, vb);
123   if ( compare_versions_funcs[i].neg )
124    ret = ret ? 0 : 1;
125
126   return ret ? 0 : 32;
127  }
128 }
129
130 ROAR_ERR("compare_versions(*): Operator \"%s\" not found.", op);
131 return 1;
132}
133
134void print_path(const char * name, int null_as_universal, const char * product, const char * provider) {
135 char * path = roar_libroar_get_path(name, null_as_universal, product, provider);
136 if ( path == NULL ) {
137  fprintf(stderr, "Error: Can not get path: %s: %s\n", name, roar_errorstring);
138  return;
139 }
140 printf("%s\n", path);
141 roar_mm_free(path);
142}
143
144void list_path(int null_as_universal, const char * product, const char * provider) {
145 const char * names[32];
146 char * path;
147 size_t offset = 0;
148 ssize_t ret;
149 ssize_t i;
150 const char * err;
151 size_t errlen;
152
153 while (1) {
154  ret = roar_libroar_list_path(names, sizeof(names)/sizeof(*names), offset);
155  if ( ret < 1 )
156   break;
157  offset += (size_t)ret;
158
159  for (i = 0; i < ret; i++) {
160   path = roar_libroar_get_path(names[i], null_as_universal, product, provider);
161   if ( path == NULL && roar_error == ROAR_ERROR_INVAL )
162    path = roar_libroar_get_path(names[i], 0, product, NULL);
163   if ( path == NULL && roar_error == ROAR_ERROR_INVAL )
164    path = roar_libroar_get_path(names[i], 0, NULL, NULL);
165   if ( path == NULL ) {
166    err = roar_errorstring;
167    errlen = roar_mm_strlen(err) + roar_mm_strlen("<Error: >") + 1;
168    path = roar_mm_malloc(errlen);
169    if ( path == NULL )
170     continue;
171    snprintf(path, errlen, "<Error: %s>", err);
172   }
173
174   printf("%-24s: %s\n", names[i], path);
175   roar_mm_free(path);
176  }
177 }
178}
179
180void print_renderpath(const char * path) {
181 char buf[1024];
182
183 if ( roar_env_render_path_r(buf, sizeof(buf), path) != 0 ) {
184  fprintf(stderr, "Error: Can not render path: %s: %s\n", path, roar_errorstring);
185  return;
186 }
187 printf("%s\n", buf);
188}
189
190void usage (void) {
191 printf("Usage: roar-config --version\n"
192        "       roar-config --compare-versions VERSIONA OPERATOR VERSIONB\n"
193        "       roar-config [{--output-pc|--output-normal}] [--libs] [--cflags] [LIB]\n"
194        "       roar-config [--product PRODUCT] [--provider PROVIDER] [--universal] {--path PATH|--list-path}\n"
195        "       roar-config --render-path PATH\n");
196
197 printf("\nOptions:\n\n");
198
199 printf("  --help              - Show this help\n"
200        "  --version           - Show version of library\n"
201        "  --compare-versions A OP B\n"
202        "                      - Compare version A against B with operator OP.\n"
203        "  --path NAME         - Print path NAME\n"
204        "  --list-path         - Print all known paths\n"
205        "  --product PRODUCT   - Product string for --path/--list-path\n"
206        "  --provider PROVIDER - Provider string for --path/--list-path\n"
207        "  --universal         - Use universal path for --path/--list-path\n"
208        "  --render-path PATH  - Print a rendered path\n"
209        "  --libs              - Show linker flags (-lxxx) needed to link library\n"
210        "  --cflags            - Show compiler flags needed to link library\n"
211        "  --output-pc         - Output PC format\n"
212        "  --output-normal     - Output in \"classical\" format\n"
213       );
214
215}
216
217#define _strcat(buf, n) strncat(buf, n, sizeof(buf)-1-strlen(buf))
218
219int main (int argc, char * argv[]) {
220 enum { NORMAL, PC } mode = NORMAL;
221 int null_as_universal = 0;
222 const char * product = NULL;
223 const char * provider = NULL;
224 int i, h;
225 int cflags = 0;
226 int libs   = 0;
227 char buf[1024] = {0};
228
229 if ( argc == 1 ) {
230  usage();
231  return 0;
232 }
233
234 for (i = 1; i < argc; i++) {
235  if ( !strcmp(argv[i], "--version") ) {
236   printf("%s\n", ROAR_VERSION_COMMON);
237  } else if ( !strcmp(argv[i], "--help") || !strcmp(argv[i], "-h") ) {
238   usage();
239   return 0;
240  } else if ( !strcmp(argv[i], "--compare-versions") ) {
241   return compare_versions(argv[i+1], argv[i+2], argv[i+3]);
242  } else if ( !strcmp(argv[i], "--product") ) {
243   product = argv[++i];
244  } else if ( !strcmp(argv[i], "--provider") ) {
245   provider = argv[++i];
246  } else if ( !strcmp(argv[i], "--universal") ) {
247   null_as_universal = 1;
248  } else if ( !strcmp(argv[i], "--path") ) {
249   print_path(argv[++i], null_as_universal, product, provider);
250  } else if ( !strcmp(argv[i], "--list-path") ) {
251   list_path(null_as_universal, product, provider);
252  } else if ( !strcmp(argv[i], "--render-path") ) {
253   print_renderpath(argv[++i]);
254  } else if ( !strcmp(argv[i], "--libs") ) {
255   libs   = 1;
256  } else if ( !strcmp(argv[i], "--cflags") ) {
257   cflags = 1;
258  } else if ( !strcmp(argv[i], "--output-normal") ) {
259   mode = NORMAL;
260  } else if ( !strcmp(argv[i], "--output-pc") ) {
261   mode = PC;
262  } else if ( flags_ptr == NULL ) {
263   if ( !strncmp(argv[i], "lib", 3) )
264    argv[i] += 3;
265
266   for (h = 0; flags[h].name != NULL; h++) {
267    if ( !strcasecmp(argv[i], flags[h].name) )
268     flags_ptr = &(flags[h]);
269   }
270
271   if ( flags_ptr == NULL ) {
272    fprintf(stderr, "Unknown lib: %s\n", argv[i]);
273    return 2;
274   }
275  } else {
276   fprintf(stderr, "Unknown option: %s\n", argv[i]);
277   usage();
278   return 1;
279  }
280 }
281
282 if ( flags_ptr == NULL )
283  flags_ptr = &(flags[0]);
284
285 switch (mode) {
286  case NORMAL:
287    if ( cflags || libs ) {
288     if ( cflags )
289      _strcat(buf, flags_ptr->cflags);
290
291     if ( libs )
292      _strcat(buf, flags_ptr->libs);
293
294     puts(buf);
295    }
296   break;
297  case PC:
298    printf("prefix=");
299    print_path("prefix", 0, NULL, NULL);
300    printf("exec_prefix=${prefix}\n");
301    printf("libdir=");
302    print_path("prefix-lib", 0, NULL, NULL);
303    printf("includedir=");
304    print_path("prefix-inc", 0, NULL, NULL);
305    printf("\n");
306    printf(
307           "Name: lib%s\n"
308           "Description: lib%s is part of RoarAudio Sound System\n"
309           "Version: %s\n"
310//           "Requires: libroar\n"
311           "Conflicts:\n"
312           "Libs: -L${libdir} %s\n"
313           "Cflags: -I${includedir} %s\n",
314           flags_ptr->name,
315           flags_ptr->name,
316           ROAR_VERSION_COMMON,
317           flags_ptr->libs,
318           flags_ptr->cflags
319          );
320   break;
321 }
322
323 return 0;
324}
325
326//ll
Note: See TracBrowser for help on using the repository browser.