static int getopt(const char * key, int op, sc68_dialval_t * val) { option68_t * opt = option68_get(key, opt68_ALWAYS); const int org = opt68_CFG; if (opt) { const int isset = opt->org != opt68_UDF; TRACE68(dial_cat, P "Got an option \"%s\" %sset opcode:%d\n", key, isset?"":"not ", op); switch (op) { case SC68_DIAL_GETI: if (isset && (opt->type == opt68_BOL || opt->type == opt68_INT || opt->type == opt68_ENU)) { val->i = opt->val.num; return 0; } break; case SC68_DIAL_GETS: if (isset && opt->type == opt68_STR) { val->s = opt->val.str; return 0; } break; case SC68_DIAL_ENUM: if (isset && opt->type == opt68_ENU && val->i >= 0 && val->i < (int)opt->sets) { val->s = val->i[(const char **)opt->set]; return 0; } break; case SC68_DIAL_SETI: return option68_iset(opt, val->i, opt68_ALWAYS, org); case SC68_DIAL_SETS: return option68_set(opt, val->s, opt68_ALWAYS, org); case SC68_DIAL_MIN: val->i = opt->min; return 0; case SC68_DIAL_MAX: val->i = opt->max; return 0; case SC68_DIAL_CNT: val->i = opt->sets; return 0; case SC68_DIAL_CAT: val->s = opt->cat; return 0; case SC68_DIAL_DESC: val->s = opt->desc; return 0; } } return -1; }
/* Load config from file */ static int load_from_file(const char * confname) { vfs68_t * is = 0; char s[256], * word; int err; option68_t * opt; strcpy(s, "sc68://config/"); strcat(s, confname); is = uri68_vfs(s, 1, 0); err = vfs68_open(is); if (err) goto error; for(;;) { char * name; int i, len, c = 0; len = vfs68_gets(is, s, sizeof(s)); if (len == -1) { err = -1; break; } if (len == 0) { break; } i = 0; /* Skip space */ while (i < len && (c=s[i++], isspace(c))) ; if (!is_symbol_char(c)) { continue; } /* Get symbol name. */ name = s+i-1; while (i < len && is_symbol_char(c = s[i++])) if (c == '_') s[i-1] = c = '-'; s[i-1] = 0; /* TRACE68(config68_cat,"conf68: load get key name='%s\n", name); */ /* Skip space */ while (i < len && isspace(c)) c=s[i++]; /* Must have '=' */ if (c != '=') { continue; } c=s[i++]; /* Skip space */ while (i < len && isspace(c)) c=s[i++]; word = s + i - 1; while (i < len && (c = s[i++]) && c != '\n'); s[i-1] = 0; opt = option68_get(name, opt68_ALWAYS); if (!opt) { TRACE68(config68_cat, "conf68: unknown config key '%s'='%s'\n", name, word); continue; } if (!opt->save) { TRACE68(config68_cat, "conf68: config key '%s'='%s' not for save\n", name, word); } TRACE68(config68_cat, "conf68: set name='%s'='%s'\n", name, word); option68_set(opt, word, opt68_PRIO, opt68_CFG); } error: vfs68_destroy(is); TRACE68(config68_cat, "conf68: loaded => [%s]\n",strok68(err)); return err; }
static int conf(void * data, const char * key, int op, sc68_dialval_t *val) { dial_t * dial = (dial_t *) data; int res = -1; static const char * l_spr[] = { "< custom >", "11 khz","22 khz", "44.1 khz","48 khz","96 khz" }; static const int i_spr[] = { 0, 11025, 22050, 44100, 48000, 96000 }; const int sprmax = sizeof (l_spr) / sizeof (*l_spr); /* Sanity check */ if (!key || !ismagic(dial)) goto exit; /* Run user control function */ res = dial->dial.cntl(dial->dial.data, key, op, val); /* Kill special case. */ if (op == SC68_DIAL_CALL && !strcmp(key,SC68_DIAL_KILL)) { del_dial(dial); goto exit; } /* User dealt with that message. */ if (res <= 0) goto exit; /* Assume no error */ res = 0; if (keyis("sampling")) { /* This key is used for the predefined sampling rate */ switch (op) { case SC68_DIAL_CNT: val->i = sprmax; break; case SC68_DIAL_GETI: { const option68_t * opt = option68_get("sampling-rate", opt68_ISSET); if (!opt) val->i = 5; /* default to 48khz */ else { for (val->i=1; val->i<sprmax; ++val->i) if (i_spr[val->i] == opt->val.num) break; if (val->i >= sprmax) val->i = 0; } } break; case SC68_DIAL_ENUM: if (val->i >= 0 && val->i < sprmax) { val->s = l_spr[val->i]; break; } default: res = -1; } } else if (op == SC68_DIAL_CALL) { /* Other special calls like real-tiem access */ if (keyis(SC68_DIAL_NEW)) val->i = 0; else if (keyis("save")) val->i = sc68_cntl(0, SC68_CONFIG_SAVE); else if (keyis("amiga-filter")) /* $$$ TODO: realtime amiga-filter */ val->i = !!val->i; else if (keyis("amiga-blend")) /* $$$ TODO: realtime amiga-blend */ val->i = val->i; } else { /* Finally try it as an option key. * * "sampling-rate" is converted if the value is in the index range * instead of the frequency value range. */ if (op == SC68_DIAL_SETI && keyis("sampling-rate") && val->i > 0 && val->i < sprmax) val->i = i_spr[val->i]; res = getopt(key, op, val); } exit: TRACE68(dial_cat, P "%s() #%02d \"%s\" -> %d\n", __FUNCTION__, op, key, res); return res; }
int file68_init(int argc, char **argv) { char tmp[1024]; option68_t * opt; if (init) { const int i = init & 3; const char *message[4] = { "clean","initialized","shutdowning","initializing" }; error68("file68: init error -- *%s*", message[i]); argc = -1; goto out_no_init; } init = 3; /* Options */ option68_init(); /* Zlib */ istream68_z_init(); /* Curl */ istream68_curl_init(); /* Xiph AO */ istream68_ao_init(); /* Init resource */ rsc68_init(); /* Loader */ file68_loader_init(); option68_append(opts,sizeof(opts)/sizeof(*opts)); argc = option68_parse(argc, argv, 1); /* Check for --sc68-no-debug */ opt = option68_get("no-debug", 1); if (opt && opt->val.num) { /* Remove all debug messages whatsoever. */ msg68_set_handler(0); } /* Check for --sc68-asid=off|safe|force */ if (opt = option68_get("asid",1), opt) { if (!strcmp68(opt->val.str,"no")) aSIDify = 0; else if (!strcmp68(opt->val.str,"safe")) aSIDify = 1; else if (!strcmp68(opt->val.str,"force")) aSIDify = 2; else msg68_notice("file68: ignore invalid mode for --sc68-asid -- *%s*\n", opt->val.str); } /* Check for --sc68-debug= */ /* postpone: at this point most debug features have not been created yet. it is pretty much useless to set the mask right now. It will be done after all inits. */ #if 0 opt = option68_get("debug", 1); if (op) { debugmsg68_mask = opt->val.num; } #endif /* Get share path from registry */ opt = option68_get("data", 0); if (opt) { /* Get data path from registry */ if (!option68_isset(opt)) { char * e; const char path[] = "Resources"; e = get_reg_path(registry68_rootkey(REGISTRY68_LMK), "SOFTWARE/sashipa/sc68/Install_Dir", tmp, sizeof(tmp)); if (e && (e+sizeof(path) < tmp+sizeof(tmp))) { memcpy(e, path, sizeof(path)); option68_set(opt,tmp); } } /* Setup new data path */ if (option68_isset(opt)) { rsc68_set_share(opt->val.str); #if 0 /* not needed anynore since option68 properly alloc strings */ if (opt->val.str == tmp) option68_unset(opt); /* Must release tmp ! */ #endif } } /* Get user path */ opt = option68_get("home", 0); if (opt) { /* Get user path from HOME */ if (!option68_isset(opt)) { const char path[] = "/.sc68"; const char * env = mygetenv("HOME"); if(env && strlen(env)+sizeof(path) < sizeof(tmp)) { strncpy(tmp,env,sizeof(tmp)); strcat68(tmp,path,sizeof(tmp)); /* $$$ We should test if this directory actually exists */ option68_set(opt,tmp); } } /* Get user path from registry */ if (!option68_isset(opt)) { char * e; const char path[] = "sc68"; e = get_reg_path(registry68_rootkey(REGISTRY68_CUK), "Volatile Environment/APPDATA", tmp, sizeof(tmp)); if (e && (e+sizeof(path) < tmp+sizeof(tmp))) { memcpy(e, path, sizeof(path)); option68_set(opt,tmp); } } /* Setup new user path */ if (option68_isset(opt)) { rsc68_set_user(opt->val.str); if (opt->val.str == tmp) option68_unset(opt); /* Must release tmp ! */ } } /* Setup new music path */ opt = option68_get("music", 1); if (opt) { rsc68_set_music(opt->val.str); } /* Setup new remote path */ opt = option68_get("remote", 1); if (opt) { rsc68_set_remote_music(opt->val.str); } init = 1; out_no_init: return argc; }