mame/3rdparty/portmidi/pm_linux/finddefault.c
2015-01-10 18:02:18 +01:00

95 lines
3.1 KiB
C

/* finddefault.c -- find_default_device() implementation
Roger Dannenberg, Jan 2009
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "portmidi.h"
extern int pm_find_default_device(char *pattern, int is_input);
#define STRING_MAX 256
/* skip over spaces, return first non-space */
void skip_spaces(FILE *inf)
{
char c;
while (isspace(c = getc(inf))) ;
ungetc(c, inf);
}
/* trim leading spaces and match a string */
int match_string(FILE *inf, char *s)
{
skip_spaces(inf);
while (*s && *s == getc(inf)) s++;
return (*s == 0);
}
/* Parse preference files, find default device, search devices --
*/
PmDeviceID find_default_device(char *path, int input, PmDeviceID id)
/* path -- the name of the preference we are searching for
input -- true iff this is an input device
id -- current default device id
returns matching device id if found, otherwise id
*/
{
static char *pref_2 = (char *)"/.java/.userPrefs/";
static char *pref_3 = (char *)"prefs.xml";
char *pref_1 = getenv("HOME");
char *full_name, *path_ptr;
FILE *inf;
int c, i;
if (!pref_1) goto nopref; // cannot find preference file
// full_name will be larger than necessary
full_name = malloc(strlen(pref_1) + strlen(pref_2) + strlen(pref_3) +
strlen(path) + 2);
strcpy(full_name, pref_1);
strcat(full_name, pref_2);
// copy all but last path segment to full_name
if (*path == '/') path++; // skip initial slash in path
path_ptr = strrchr(path, '/');
if (path_ptr) { // copy up to slash after full_name
path_ptr++;
int offset = strlen(full_name);
memcpy(full_name + offset, path, path_ptr - path);
full_name[offset + path_ptr - path] = 0; // end of string
} else {
path_ptr = path;
}
strcat(full_name, pref_3);
inf = fopen(full_name, "r");
free(full_name);
if (!inf) goto nopref; // cannot open preference file
// We're not going to build or link in a full XML parser.
// Instead, find the path string and quoute. Then, look for
// "value", "=", quote. Then get string up to quote.
while ((c = getc(inf)) != EOF) {
char pref_str[STRING_MAX];
if (c != '"') continue; // scan up to quote
// look for quote string quote
if (!match_string(inf, path_ptr)) continue; // path not found
if (getc(inf) != '"') continue; // path not found, keep scanning
if (!match_string(inf, (char *)"value")) goto nopref; // value not found
if (!match_string(inf, (char *)"=")) goto nopref; // = not found
if (!match_string(inf, (char *)"\"")) goto nopref; // quote not found
// now read the value up to the close quote
for (i = 0; i < STRING_MAX; i++) {
if ((c = getc(inf)) == '"') break;
pref_str[i] = c;
}
if (i == STRING_MAX) continue; // value too long, ignore
pref_str[i] = 0;
i = pm_find_default_device(pref_str, input);
if (i != pmNoDevice) {
id = i;
}
break;
}
nopref:
return id;
}