finddefault.c (3085B)
1 /* finddefault.c -- find_default_device() implementation 2 Roger Dannenberg, Jan 2009 3 */ 4 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <ctype.h> 9 10 #include "portmidi.h" 11 12 #define STRING_MAX 256 13 14 int pm_find_default_device(char *pattern, int is_input); 15 16 /* skip over spaces, return first non-space */ 17 void skip_spaces(FILE *inf) 18 { 19 char c; 20 while (isspace(c = getc(inf))) ; 21 ungetc(c, inf); 22 } 23 24 /* trim leading spaces and match a string */ 25 int match_string(FILE *inf, char *s) 26 { 27 skip_spaces(inf); 28 while (*s && *s == getc(inf)) s++; 29 return (*s == 0); 30 } 31 32 33 /* 34 /* Parse preference files, find default device, search devices -- 35 */ 36 PmDeviceID find_default_device(char *path, int input, PmDeviceID id) 37 /* path -- the name of the preference we are searching for 38 input -- true iff this is an input device 39 id -- current default device id 40 returns matching device id if found, otherwise id 41 */ 42 { 43 static char *pref_2 = "/.java/.userPrefs/"; 44 static char *pref_3 = "prefs.xml"; 45 char *pref_1 = getenv("HOME"); 46 char *full_name, *path_ptr; 47 FILE *inf; 48 int c, i; 49 if (!pref_1) goto nopref; // cannot find preference file 50 // full_name will be larger than necessary 51 full_name = malloc(strlen(pref_1) + strlen(pref_2) + strlen(pref_3) + 52 strlen(path) + 2); 53 strcpy(full_name, pref_1); 54 strcat(full_name, pref_2); 55 // copy all but last path segment to full_name 56 if (*path == '/') path++; // skip initial slash in path 57 path_ptr = strrchr(path, '/'); 58 if (path_ptr) { // copy up to slash after full_name 59 path_ptr++; 60 int offset = strlen(full_name); 61 memcpy(full_name + offset, path, path_ptr - path); 62 full_name[offset + path_ptr - path] = 0; // end of string 63 } else { 64 path_ptr = path; 65 } 66 strcat(full_name, pref_3); 67 inf = fopen(full_name, "r"); 68 if (!inf) goto nopref; // cannot open preference file 69 // We're not going to build or link in a full XML parser. 70 // Instead, find the path string and quoute. Then, look for 71 // "value", "=", quote. Then get string up to quote. 72 while ((c = getc(inf)) != EOF) { 73 char pref_str[STRING_MAX]; 74 if (c != '"') continue; // scan up to quote 75 // look for quote string quote 76 if (!match_string(inf, path_ptr)) continue; // path not found 77 if (getc(inf) != '"') continue; // path not found, keep scanning 78 if (!match_string(inf, "value")) goto nopref; // value not found 79 if (!match_string(inf, "=")) goto nopref; // = not found 80 if (!match_string(inf, "\"")) goto nopref; // quote not found 81 // now read the value up to the close quote 82 for (i = 0; i < STRING_MAX; i++) { 83 if ((c = getc(inf)) == '"') break; 84 pref_str[i] = c; 85 } 86 if (i == STRING_MAX) continue; // value too long, ignore 87 pref_str[i] == 0; 88 i = pm_find_default_device(pref_str, input); 89 if (i != pmNoDevice) { 90 id = i; 91 } 92 break; 93 } 94 nopref: 95 return id; 96 }