RepoWrapper::RepoWrapper(const char* repoSchema, const std::string& configFile) { if (setenv("HHVM_RUNTIME_REPO_SCHEMA", repoSchema, 1 /* overwrite */)) { fprintf(stderr, "Could not set repo schema"); exit(EXIT_FAILURE); } printf("# Config file: %s\n", configFile.c_str()); printf("# Repo schema: %s\n", repoSchemaId().begin()); register_process_init(); initialize_repo(); hphp_thread_init(); g_context.getCheck(); IniSetting::Map ini = IniSetting::Map::object; Hdf config; if (!configFile.empty()) { Config::ParseConfigFile(configFile, ini, config); // Disable logging to suppress harmless errors about setrlimit. config["Log"]["Level"] = "None"; } RuntimeOption::Load(ini, config); RuntimeOption::RepoCommit = false; compile_file(nullptr, 0, MD5(), nullptr); repo = &Repo::get(); RuntimeOption::AlwaysUseRelativePath = false; RuntimeOption::SafeFileAccess = false; RuntimeOption::EvalAllowHhas = true; Option::WholeProgram = false; LitstrTable::init(); LitstrTable::get().setWriting(); RuntimeOption::RepoAuthoritative = true; repo->loadGlobalData(true /* allowFailure */); std::string hhasLib; auto const phpLib = get_systemlib(&hhasLib); always_assert(!hhasLib.empty() && !phpLib.empty()); auto phpUnit = compile_string(phpLib.c_str(), phpLib.size(), "systemlib.php"); addUnit(phpUnit); auto hhasUnit = compile_string(hhasLib.c_str(), hhasLib.size(), "systemlib.hhas"); addUnit(hhasUnit); SystemLib::s_inited = true; LitstrTable::get().setReading(); }
void Extension::CompileSystemlib(const std::string &slib, const std::string &name) { Unit *unit = compile_string(slib.c_str(), slib.size(), name.c_str()); assert(unit); unit->merge(); s_systemlib_units.push_back(unit); }
void compile_topology(int kflag) { extern char *compile_string(char *, int); char *so_file; int n; #if defined(APPEND_DOT_TO_LDPATH) { extern int putenv(char *); char *newenv, *oldenv; if((oldenv = findenv("LD_LIBRARY_PATH", NULL)) == (char *)NULL) newenv = strdup("LD_LIBRARY_PATH=\".\""); else { sprintf(chararray,"LD_LIBRARY_PATH=\"%s:.\"", oldenv); newenv = strdup(chararray); } putenv(newenv); } #endif for(n=0 ; n<_NNODES ; n++) { so_file = compile_string(NP[n].nattr.compile, kflag); if(nerrors) cleanup(1); dynamic_load(n, so_file); if(nerrors) cleanup(1); } }
Unit* compile_systemlib_string(const char* s, size_t sz, const char* fname, const Native::FuncTable& nativeFuncs) { assertx(fname[0] == '/' && fname[1] == ':'); if (auto u = lookupSyslibUnit(makeStaticString(fname), nativeFuncs)) { return u; } return compile_string(s, sz, fname, nativeFuncs); }
void test_compile_fmt() /* {{{ */ { /* test compiling a format to a series of fields */ fmt_field *fmts; char *eval, *teststr; teststr = "first $date $-8program_version $4program_name $10program_author ++?$search_string?SEARCH??++ ++?$active_filter??NO?++ second"; fmts = compile_string(teststr); eval = eval_format(fmts, NULL); if (eval != NULL) printf("%s\n", eval); else puts("NULL returned"); teststr = "first uuid:'$uuid' pro:'$project' desc:'$description' $badvar second"; fmts = compile_string(teststr); eval = eval_format(fmts, head); if (eval != NULL) printf("%s\n", eval); else puts("NULL returned"); } /* }}} */
Unit* InjectionCache::getUnit(const StringData* code) { ReadLock lock(m_lock); // Note: caller needs to make sure the parameter code is not temporary UnitMap::accessor acc; if (m_unitCache.insert(acc, code)) { Unit* unit = compile_string(code->data(), code->size()); // Here we save it even if unit == NULL, that at least saves us from // compiling same illegal string acc->second = unit; } return acc->second; }
Unit* compile_systemlib_string(const char* s, size_t sz, const char* fname) { if (RuntimeOption::RepoAuthoritative) { String systemName = String("/:") + fname; auto md5 = MD5{mangleSystemMd5(string_md5(folly::StringPiece{s,sz}))}; if (Repo::get().findFile(systemName.data(), SourceRootInfo::GetCurrentSourceRoot(), md5)) { if (auto u = Repo::get().loadUnit(fname, md5)) { return u.release(); } } } return compile_string(s, sz, fname); }
void define_hook(fcode_env_t *env, char *name, int len, char *fcimage) { static void (*byteload_ptr)(fcode_env_t *env) = byte_loadfile; header(env, name, len, 0); COMPILE_TOKEN(&do_colon); env->state |= 1; PUSH(DS, (fstack_t) fcimage); PUSH(DS, strlen(fcimage)); compile_string(env); COMPILE_TOKEN(&byteload_ptr); semi(env); }
Unit* compile_systemlib_string(const char* s, size_t sz, const char* fname) { if (RuntimeOption::RepoAuthoritative) { String systemName = String("/:") + String(fname); MD5 md5; if (Repo::get().findFile(systemName.data(), SourceRootInfo::GetCurrentSourceRoot(), md5)) { if (auto u = Repo::get().loadUnit(fname, md5)) { return u.release(); } } } return compile_string(s, sz, fname); }
int main(int argc, char **argv) { int opt; int max_cache_entries = CCNL_DEFAULT_MAX_CACHE_ENTRIES; // srand(time(NULL)); srandom(time(NULL)); while ((opt = getopt(argc, argv, "hc:g:i:s:v:")) != -1) { switch (opt) { case 'c': max_cache_entries = atoi(optarg); break; case 'g': inter_packet_interval = atoi(optarg); break; case 'i': inter_ccn_interval = atoi(optarg); break; case 'v': if (isdigit(optarg[0])) debug_level = atoi(optarg); else debug_level = ccnl_debug_str2level(optarg); break; case 's': theSuite = ccnl_str2suite(optarg); if (theSuite >= 0 && theSuite < CCNL_SUITE_LAST) break; case 'h': default: fprintf(stderr, "Xusage: %s [-h] [-c MAX_CONTENT_ENTRIES] " "[-g MIN_INTER_PACKET_INTERVAL] " "[-i MIN_INTER_CCNMSG_INTERVAL] " "[-s SUITE (ccnb, ccnx2014, iot2014, ndn2013)] " "[-v DEBUG_LEVEL]\n", argv[0]); exit(EXIT_FAILURE); } } time(&relays[0].startup_time); ccnl_core_init(); DEBUGMSG(INFO, "This is ccn-lite-simu, starting at %s", ctime(&relays[0].startup_time) + 4); DEBUGMSG(INFO, " ccnl-core: %s\n", CCNL_VERSION); DEBUGMSG(INFO, " compile time: %s %s\n", __DATE__, __TIME__); DEBUGMSG(INFO, " compile options: %s\n", compile_string()); DEBUGMSG(INFO, "using suite %s\n", ccnl_suite2str(theSuite)); ccnl_simu_init(max_cache_entries); DEBUGMSG(INFO, "simulation starts\n"); simu_eventloop(); DEBUGMSG(INFO, "simulation ends\n"); return -1; }
void ProcessInit() { // Create the global mcg object jit::mcg = new jit::MCGenerator(); jit::mcg->initUniqueStubs(); // Save the current options, and set things up so that // systemlib.php can be read from and stored in the // normal repo. int db = RuntimeOption::EvalDumpBytecode; bool rp = RuntimeOption::AlwaysUseRelativePath; bool sf = RuntimeOption::SafeFileAccess; bool ah = RuntimeOption::EvalAllowHhas; bool wp = Option::WholeProgram; RuntimeOption::EvalDumpBytecode &= ~1; RuntimeOption::AlwaysUseRelativePath = false; RuntimeOption::SafeFileAccess = false; RuntimeOption::EvalAllowHhas = true; Option::WholeProgram = false; RDS::requestInit(); string hhas; string slib = get_systemlib(&hhas); if (slib.empty()) { // Die a horrible death. Logger::Error("Unable to find/load systemlib.php"); _exit(1); } LitstrTable::init(); LitstrTable::get().setWriting(); Repo::get().loadGlobalData(); // Save this in case the debugger needs it. Once we know if this // process does not have debugger support, we'll clear it. SystemLib::s_source = slib; SystemLib::s_unit = compile_systemlib_string(slib.c_str(), slib.size(), "systemlib.php"); const StringData* msg; int line; if (SystemLib::s_unit->compileTimeFatal(msg, line)) { Logger::Error("An error has been introduced into the systemlib, " "but we cannot give you a file and line number right now."); Logger::Error("Check all of your changes to hphp/system/php"); Logger::Error("HipHop Parse Error: %s", msg->data()); _exit(1); } if (!hhas.empty()) { SystemLib::s_hhas_unit = compile_string(hhas.c_str(), hhas.size(), "systemlib.hhas"); if (SystemLib::s_hhas_unit->compileTimeFatal(msg, line)) { Logger::Error("An error has been introduced in the hhas portion of " "systemlib."); Logger::Error("Check all of your changes to hhas files in " "hphp/system/php"); Logger::Error("HipHop Parse Error: %s", msg->data()); _exit(1); } } // Load the systemlib unit to build the Class objects SystemLib::s_unit->merge(); if (SystemLib::s_hhas_unit) { SystemLib::s_hhas_unit->merge(); } SystemLib::s_nativeFuncUnit = build_native_func_unit(hhbc_ext_funcs, hhbc_ext_funcs_count); SystemLib::s_nativeFuncUnit->merge(); SystemLib::s_nullFunc = Unit::lookupFunc(makeStaticString("86null")); // We call a special bytecode emitter function to build the native // unit which will contain all of our cppext functions and classes. // Each function and method will have a bytecode body that will thunk // to the native implementation. Unit* nativeClassUnit = build_native_class_unit(hhbc_ext_classes, hhbc_ext_class_count); SystemLib::s_nativeClassUnit = nativeClassUnit; LitstrTable::get().setReading(); // Load the nativelib unit to build the Class objects SystemLib::s_nativeClassUnit->merge(); #define INIT_SYSTEMLIB_CLASS_FIELD(cls) \ { \ Class *cls = NamedEntity::get(s_##cls.get())->clsList(); \ assert(!hhbc_ext_class_count || cls); \ SystemLib::s_##cls##Class = cls; \ } // Stash a pointer to the VM Classes for stdclass, Exception, // pinitSentinel and resource SYSTEMLIB_CLASSES(INIT_SYSTEMLIB_CLASS_FIELD) #undef INIT_SYSTEMLIB_CLASS_FIELD // Retrieve all of the class pointers for (long long i = 0; i < hhbc_ext_class_count; ++i) { const HhbcExtClassInfo* info = hhbc_ext_classes + i; const StringData* name = makeStaticString(info->m_name); const NamedEntity* ne = NamedEntity::get(name); Class* cls = Unit::lookupClass(ne); assert(cls); *(info->m_clsPtr) = cls; } ClassInfo::InitializeSystemConstants(); Stack::ValidateStackSize(); SystemLib::s_inited = true; RuntimeOption::AlwaysUseRelativePath = rp; RuntimeOption::SafeFileAccess = sf; RuntimeOption::EvalDumpBytecode = db; RuntimeOption::EvalAllowHhas = ah; Option::WholeProgram = wp; folly::SingletonVault::singleton()->registrationComplete(); }
int main(int argc, char **argv) { int opt; int max_cache_entries = -1; int udpport = CCN_UDP_PORT; int tcpport = CCN_UDP_PORT; char *datadir = NULL; char *ethdev = NULL; char *crypto_sock_path = 0; #ifdef USE_UNIXSOCKET char *uxpath = CCNL_DEFAULT_UNIXSOCKNAME; #else char *uxpath = NULL; #endif time(&theRelay.startup_time); srandom(time(NULL)); while ((opt = getopt(argc, argv, "hc:d:e:g:i:s:u:v:x:p:")) != -1) { switch (opt) { case 'c': max_cache_entries = atoi(optarg); break; case 'd': datadir = optarg; break; case 'e': ethdev = optarg; break; case 'g': inter_pkt_interval = atoi(optarg); break; case 'i': inter_ccn_interval = atoi(optarg); break; case 's': tcpport = atoi(optarg); break; case 'u': udpport = atoi(optarg); break; case 'v': debug_level = atoi(optarg); break; case 'x': uxpath = optarg; break; case 'p': crypto_sock_path = optarg; break; case 'h': default: fprintf(stderr, "usage: %s [-h] [-c MAX_CONTENT_ENTRIES]" " [-d databasedir]" " [-e ethdev]" " [-g MIN_INTER_PACKET_INTERVAL]" " [-i MIN_INTER_CCNMSG_INTERVAL]" " [-s tcpport]" " [-u udpport]" " [-v DEBUG_LEVEL]" #ifdef USE_UNIXSOCKET " [-p crypto_face_ux_socket]" " [-x unixpath]" #endif "\n", argv[0]); exit(EXIT_FAILURE); } } DEBUGMSG(1, "This is ccn-lite-relay, starting at %s", ctime(&theRelay.startup_time) + 4); DEBUGMSG(1, " ccnl-core: %s\n", CCNL_VERSION); DEBUGMSG(1, " compile time: %s %s\n", __DATE__, __TIME__); DEBUGMSG(1, " compile options: %s\n", compile_string()); ccnl_relay_config(&theRelay, ethdev, udpport, tcpport, uxpath, max_cache_entries, crypto_sock_path); if (datadir) ccnl_populate_cache(&theRelay, datadir); ccnl_io_loop(&theRelay); while (eventqueue) ccnl_rem_timer(eventqueue); ccnl_core_cleanup(&theRelay); #ifdef USE_HTTP_STATUS theRelay.http = ccnl_http_cleanup(theRelay.http); #endif #ifdef USE_DEBUG_MALLOC debug_memdump(); #endif return 0; }
Unit* compile_debugger_string(const char* s, size_t sz) { return compile_string(s, sz, nullptr, Native::s_noNativeFuncs, true); }
int ccnl_http_status(struct ccnl_relay_s *ccnl, struct ccnl_http_s *http) { static char txt[64000]; char *hdr = "HTTP/1.1 200 OK\n\r" "Content-Type: text/html; charset=utf-8\n\r" "Connection: close\n\r\n\r", *cp; int len = strlen(hdr), i, j, cnt; time_t t; struct utsname uts; struct ccnl_face_s *f; struct ccnl_forward_s *fwd; struct ccnl_interest_s *ipt; struct ccnl_buf_s *bpt; strcpy(txt, hdr); len += sprintf(txt+len, "<html><head><title>ccn-lite-relay status</title>\n" "<style type=\"text/css\">\n" "body {font-family: sans-serif;}\n" "</style>\n" "</head><body>\n"); len += sprintf(txt+len, "\n<table borders=0>\n<tr><td>" "<a href=\"\">[refresh]</a> <td>" "ccn-lite-relay Status Page "); uname(&uts); len += sprintf(txt+len, "node <strong>%s (%d)</strong>\n", uts.nodename, getpid()); t = time(NULL); cp = ctime(&t); cp[strlen(cp)-1] = 0; len += sprintf(txt+len, "<tr><td><td><font size=-1>%s ", cp); cp = ctime(&ccnl->startup_time); cp[strlen(cp)-1] = 0; len += sprintf(txt+len, " (started %s)</font>\n</table>\n", cp); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Forwarding Table</em></table><ul>\n"); for (fwd = ccnl->fib, cnt = 0; fwd; fwd = fwd->next, cnt++); if (cnt > 0) { struct ccnl_forward_s **fwda; fwda = (struct ccnl_forward_s**) ccnl_malloc(cnt * sizeof(fwd)); for (fwd = ccnl->fib, i = 0; fwd; fwd = fwd->next, i++) fwda[i] = fwd; qsort(fwda, cnt, sizeof(fwd), ccnl_cmpfib); for (i = 0; i < cnt; i++) { char fname[10]; sprintf(fname, "f%d", fwda[i]->face->faceid); len += sprintf(txt+len, "<li>via %4s: <font face=courier>%s</font>\n", fname, ccnl_prefix_to_path(fwda[i]->prefix)); } ccnl_free(fwda); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Faces</em></table><ul>\n"); for (f = ccnl->faces, cnt = 0; f; f = f->next, cnt++); if (cnt > 0) { struct ccnl_face_s **fa; fa = (struct ccnl_face_s**) ccnl_malloc(cnt * sizeof(f)); for (f = ccnl->faces, i = 0; f; f = f->next, i++) fa[i] = f; qsort(fa, cnt, sizeof(f), ccnl_cmpfaceid); for (i = 0; i < cnt; i++) { len += sprintf(txt+len, "<li><strong>f%d</strong> (via i%d) " "peer=<font face=courier>%s</font> ttl=", fa[i]->faceid, fa[i]->ifndx, ccnl_addr2ascii(&(fa[i]->peer))); if (fa[i]->flags & CCNL_FACE_FLAGS_STATIC) len += sprintf(txt+len, "static"); else len += sprintf(txt+len, "%.1fsec", fa[i]->last_used + CCNL_FACE_TIMEOUT - CCNL_NOW()); for (j = 0, bpt = fa[i]->outq; bpt; bpt = bpt->next, j++); len += sprintf(txt+len, " qlen=%d\n", j); } ccnl_free(fa); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Interfaces</em></table><ul>\n"); for (i = 0; i < ccnl->ifcount; i++) { len += sprintf(txt+len, "<li><strong>i%d</strong> " "addr=<font face=courier>%s</font> " "qlen=%d/%d\n", i, ccnl_addr2ascii(&ccnl->ifs[i].addr), ccnl->ifs[i].qlen, CCNL_MAX_IF_QLEN); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Misc stats</em></table><ul>\n"); for (cnt = 0, bpt = ccnl->nonces; bpt; bpt = bpt->next, cnt++); len += sprintf(txt+len, "<li>Nonces: %d\n", cnt); for (cnt = 0, ipt = ccnl->pit; ipt; ipt = ipt->next, cnt++); len += sprintf(txt+len, "<li>Pending interests: %d\n", cnt); len += sprintf(txt+len, "<li>Content chunks: %d (max=%d)\n", ccnl->contentcnt, ccnl->max_cache_entries); len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Config</em></table><table borders=0>\n"); len += sprintf(txt+len, "<tr><td>content.timeout:" "<td align=right> %d<td>\n", CCNL_CONTENT_TIMEOUT); len += sprintf(txt+len, "<tr><td>face.timeout:" "<td align=right> %d<td>\n", CCNL_FACE_TIMEOUT); len += sprintf(txt+len, "<tr><td>interest.maxretransmit:" "<td align=right> %d<td>\n", CCNL_MAX_INTEREST_RETRANSMIT); len += sprintf(txt+len, "<tr><td>interest.timeout:" "<td align=right> %d<td>\n", CCNL_INTEREST_TIMEOUT); len += sprintf(txt+len, "<tr><td>nonces.max:" "<td align=right> %d<td>\n", CCNL_MAX_NONCES); len += sprintf(txt+len, "<tr><td>compile.featureset:<td><td> %s\n", compile_string()); len += sprintf(txt+len, "<tr><td>compile.time:" "<td><td>%s %s\n", __DATE__, __TIME__); len += sprintf(txt+len, "<tr><td>compile.ccnl_core_version:" "<td><td>%s\n", CCNL_VERSION); len += sprintf(txt+len, "</table>\n"); len += sprintf(txt+len, "\n<p><hr></body></html>\n"); http->out = (unsigned char*) txt; http->outoffs = 0; http->outlen = len; return 0; }
void ProcessInit() { // Install VM's ClassInfoHook ClassInfo::SetHook(&vm_class_info_hook); // ensure that nextTx64 and tx64 are set (void)Transl::Translator::Get(); // Save the current options, and set things up so that // systemlib.php can be read from and stored in the // normal repo. int db = RuntimeOption::EvalDumpBytecode; bool rp = RuntimeOption::AlwaysUseRelativePath; bool sf = RuntimeOption::SafeFileAccess; bool ah = RuntimeOption::EvalAllowHhas; RuntimeOption::EvalDumpBytecode &= ~1; RuntimeOption::AlwaysUseRelativePath = false; RuntimeOption::SafeFileAccess = false; RuntimeOption::EvalAllowHhas = true; Transl::TargetCache::requestInit(); string hhas; string slib = get_systemlib(&hhas); if (slib.empty()) { // Die a horrible death. Logger::Error("Unable to find/load systemlib.php"); _exit(1); } // Save this in case the debugger needs it. Once we know if this // process does not have debugger support, we'll clear it. SystemLib::s_source = slib; SystemLib::s_unit = compile_string(slib.c_str(), slib.size(), "systemlib.php"); if (!hhas.empty()) { SystemLib::s_hhas_unit = compile_string(hhas.c_str(), hhas.size(), "systemlib.hhas"); } // Load the systemlib unit to build the Class objects SystemLib::s_unit->merge(); if (SystemLib::s_hhas_unit) { SystemLib::s_hhas_unit->merge(); } SystemLib::s_nativeFuncUnit = build_native_func_unit(hhbc_ext_funcs, hhbc_ext_funcs_count); SystemLib::s_nativeFuncUnit->merge(); SystemLib::s_nullFunc = Unit::lookupFunc(makeStaticString("86null")); // We call a special bytecode emitter function to build the native // unit which will contain all of our cppext functions and classes. // Each function and method will have a bytecode body that will thunk // to the native implementation. Unit* nativeClassUnit = build_native_class_unit(hhbc_ext_classes, hhbc_ext_class_count); SystemLib::s_nativeClassUnit = nativeClassUnit; // Load the nativelib unit to build the Class objects SystemLib::s_nativeClassUnit->merge(); #define INIT_SYSTEMLIB_CLASS_FIELD(cls) \ { \ Class *cls = Unit::GetNamedEntity(s_##cls.get())->clsList(); \ assert(!hhbc_ext_class_count || cls); \ SystemLib::s_##cls##Class = cls; \ } // Stash a pointer to the VM Classes for stdclass, Exception, // pinitSentinel and resource SYSTEMLIB_CLASSES(INIT_SYSTEMLIB_CLASS_FIELD) #undef INIT_SYSTEMLIB_CLASS_FIELD // Retrieve all of the class pointers for (long long i = 0; i < hhbc_ext_class_count; ++i) { const HhbcExtClassInfo* info = hhbc_ext_classes + i; const StringData* name = makeStaticString(info->m_name); const NamedEntity* ne = Unit::GetNamedEntity(name); Class* cls = Unit::lookupClass(ne); assert(cls); *(info->m_clsPtr) = cls; } ClassInfo::InitializeSystemConstants(); Stack::ValidateStackSize(); SystemLib::s_inited = true; RuntimeOption::AlwaysUseRelativePath = rp; RuntimeOption::SafeFileAccess = sf; RuntimeOption::EvalDumpBytecode = db; RuntimeOption::EvalAllowHhas = ah; }
Unit* compile_systemlib_string(const char* s, size_t sz, const char* fname) { assertx(fname[0] == '/' && fname[1] == ':'); if (auto u = lookupSyslibUnit(makeStaticString(fname))) return u; return compile_string(s, sz, fname); }
int main(int argc, char *argv[]) { int opt; if (argc == 1) { usage(); } if (argc == 2 && strcmp(argv[1], "-r") == 0) { init(); read_pedals(); deinit(); return 0; } init_pedals(); while ((opt = getopt(argc, argv, "123rs:S:a:k:m:b:x:y:w:")) != -1) { switch (opt) { case '1': curr_pedal = &pd.pedals[0]; break; case '2': curr_pedal = &pd.pedals[1]; break; case '3': curr_pedal = &pd.pedals[2]; break; case 'r': fprintf(stderr, "Cannot use -r with other options\n"); return 1; case 's': compile_string(optarg); break; case 'S': compile_raw_string(optarg); break; case 'a': compile_string_key(optarg); break; case 'k': compile_key(optarg); break; case 'm': compile_modifier(optarg); break; case 'b': compile_mouse_button(optarg); break; case 'x': compile_mouse_xyw(optarg, NULL, NULL); break; case 'y': compile_mouse_xyw(NULL, optarg, NULL); break; case 'w': compile_mouse_xyw(NULL, NULL, optarg); break; default: usage(); break; } } init(); write_pedals(); deinit(); return 0; }