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); }
int main(int argc, char* argv[]) { std::cout << "\n Testing SemiExp class\n " << std::string(23,'=') << std::endl; std::cout << "\n testing SemiExp::find()"; std::cout << "\n -------------------------"; SemiExp semi(0); semi.push_back("one"); semi.push_back("two"); semi.push_back("three"); semi.push_back("four"); std::cout << "\n" << semi.show(); size_t pos = semi.find("two"); std::cout << "\n position of \"two\" is " << pos; pos = semi.find("foobar"); std::cout << "\n position of \"foobar\" is " << pos; std::cout << "\n\n"; std::cout << "\n Note that comments and quotes are returned as single tokens\n"; if(argc < 2) { std::cout << "\n please enter name of file to process on command line\n\n"; return 1; } for(int i=1; i<argc; ++i) { std::cout << "\n Processing file " << argv[i]; std::cout << "\n " << std::string(16 + strlen(argv[i]),'-') << "\n\n"; try { Toker toker(argv[i]); toker.returnComments(); SemiExp se(&toker); se.makeCommentSemiExp(); // se.verbose(); // uncomment to show token details while(se.get()) std::cout << se.show().c_str() << std::endl; std::cout << "\n"; } catch(std::exception ex) { std::cout << "\n " << ex.what() << "\n\n"; } } }
static void for_stmt(void) { int ls, lbody, lb, lc; Token = scan(); ls = label(); lbody = label(); pushbrk(lb = label()); pushcont(lc = label()); lparen(); if (Token != SEMI) { rexpr(); clear(); } semi(); genlab(ls); if (Token != SEMI) { rexpr(); clear(); genbrfalse(lb); } genjump(lbody); semi(); genlab(lc); if (Token != RPAREN) { rexpr(); clear(); } genjump(ls); rparen(); genlab(lbody); stmt(); genjump(lc); genlab(lb); Bsp--; Csp--; }
void define_actions(fcode_env_t *env, int n, token_t *array) { int a; PUSH(DS, (fstack_t)n); actions(env); a = 0; while (n--) { action_colon(env); COMPILE_TOKEN(&array[a]); env->state |= 8; semi(env); a++; } }
static void return_stmt(void) { int lv[LV]; Token = scan(); if (Token != SEMI) { if (expr(lv)) rvalue(lv); if (!typematch(lv[LVPRIM], Prims[Thisfn])) error("incompatible type in 'return'", NULL); } else { if (Prims[Thisfn] != PVOID) error("missing value after 'return'", NULL); } genjump(Retlab); semi(); }
static void do_stmt(void) { int ls, lb, lc; Token = scan(); ls = label(); pushbrk(lb = label()); pushcont(lc = label()); genlab(ls); stmt(); match(WHILE, "'while'"); lparen(); genlab(lc); rexpr(); genbrtrue(ls); genlab(lb); rparen(); semi(); Bsp--; Csp--; }
int main(int argc, char* argv[]) { std::cout << "\n Testing SemiExp class\n " << std::string(23,'=') << std::endl; try { std::cout << "\n testing SemiExp::get(...)"; std::cout << "\n -----------------------------"; Toker toker1(argv[1]); toker1.returnComments(false); SemiExp test1(&toker1); test1.get(); std::cout << "\n " << test1.show(); test1.get(false); std::cout << "\n " << test1.show(); test1.get(); std::cout << "\n " << test1.show(); test1.get(false); std::cout << "\n " << test1.show() << std::endl; std::cout << "\n testing SemiExp::merge(...)"; std::cout << "\n -----------------------------"; SemiExp test2(0); test2.push_back("one"); test2.push_back("two"); test2.push_back("three"); test2.push_back("four"); test2.push_back("five"); std::cout << "\n " << test2.show(); test2.merge("two","five"); std::cout << "\n " << test2.show() << std::endl; std::cout << "\n testing SemiExp::find()"; std::cout << "\n -------------------------"; SemiExp semi(0); semi.push_back("one"); semi.push_back("two"); semi.push_back("three"); semi.push_back("four"); std::cout << "\n" << semi.show(); size_t pos = semi.find("two"); std::cout << "\n position of \"two\" is " << pos; pos = semi.find("foobar"); std::cout << "\n position of \"foobar\" is " << pos; std::cout << "\n\n"; std::cout << "\n Note that comments and quotes are returned as single tokens\n"; } catch(std::exception& ex) { std::cout << "\n\n " << ex.what() << "\n\n"; return 1; } if(argc < 2) { std::cout << "\n please enter name of file to process on command line\n\n"; return 1; } for(int i=1; i<argc; ++i) { std::cout << "\n Processing file " << argv[i]; std::cout << "\n " << std::string(16 + strlen(argv[i]),'-') << "\n\n"; try { Toker toker(argv[i]); toker.returnComments(); SemiExp se(&toker); se.makeCommentSemiExp(); //se.verbose(); // uncomment to show token details while(se.get()) { std::cout << se.show(true).c_str() << std::endl; for(size_t i=0; i<se.length(); ++i) if(se[i] == "") std::cout << "\n\n----blank token----\n"; } std::cout << "\n"; } catch(std::exception ex) { std::cout << "\n " << ex.what() << "\n\n"; } } for(int i=1; i<argc; ++i) { std::cout << "\n Processing file " << argv[i]; std::cout << "\n " << std::string(16 + strlen(argv[i]),'-') << "\n\n"; try { Toker toker(argv[i]); toker.returnComments(); SemiExp se(&toker); se.makeCommentSemiExp(); se.returnNewLines(false); //se.verbose(); // uncomment to show token details while(se.get()) { for(size_t i=0; i<se.length(); ++i) if(se[i] == "") std::cout << "\n\n----blank token----\n"; std::cout << se.show(true).c_str() << std::endl; } std::cout << "\n"; } catch(std::exception ex) { std::cout << "\n " << ex.what() << "\n\n"; } } }
static Type* parsedefn(char *p, Type *t, char **pp) { char c, *name; int ischar, namelen, n, wid, offset, bits, sign; long val; Type *tt; if(*p == '(' || isdigit((uchar)*p)){ t->ty = Defer; t->sub = parseinfo(p, pp); return t; } switch(c = *p){ case '-': /* builtin */ n = strtol(p+1, &p, 10); if(n >= nelem(baseints) || n < 0) n = 0; t->ty = Base; t->xsizeof = baseints[n].size; t->printfmt = baseints[n].fmt; break; case 'b': /* builtin */ p++; if(*p != 'u' && *p != 's') oops(); sign = (*p == 's'); p++; ischar = 0; if(*p == 'c'){ ischar = 1; p++; } wid = parseint(&p); semi(&p); offset = parseint(&p); semi(&p); bits = parseint(&p); semi(&p); t->ty = Base; t->xsizeof = wid; if(sign == 1) t->printfmt = 'd'; else t->printfmt = 'x'; USED(bits); USED(ischar); break; case 'R': /* fp type */ n = parseint(&p); semi(&p); wid = parseint(&p); semi(&p); t->ty = Base; t->xsizeof = wid; if(n < 0 || n >= nelem(basefloats)) n = 0; t->xsizeof = basefloats[n].size; t->printfmt = basefloats[n].fmt; break; case 'r': /* subrange */ t->ty = Range; t->sub = parseinfo(p+1, &p); if(*(p-1) == ';' && *p != ';') p--; semi(&p); t->lo = parsebound(&p); semi(&p); t->hi = parsebound(&p); semi(&p); break; case 'B': /* volatile */ case 'k': /* const */ t->ty = Defer; t->sub = parseinfo(p+1, &p); break; case '*': /* pointer */ case 'A': /* open array */ case '&': /* reference */ /* guess - C++? (rob) */ t->ty = Pointer; t->sub = parseinfo(p+1, &p); break; case 'a': /* array */ case 'P': /* packed array */ t->ty = Pointer; tt = newtype(); parsedefn(p+1, tt, &p); /* index type */ if(*p == ';') p++; tt = newtype(); t->sub = tt; parsedefn(p, tt, &p); /* element type */ break; case 'e': /* enum listing */ p++; t->sue = 'e'; t->ty = Enum; while(*p != ';'){ name = p; p = findcolon(p)+1; namelen = (p-name)-1; val = parsebigint(&p); comma(&p); if(t->n%32 == 0){ t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0])); t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0])); } t->tname[t->n] = estrndup(name, namelen); t->val[t->n] = val; t->n++; } semi(&p); break; case 's': /* struct */ case 'u': /* union */ p++; t->sue = c; t->ty = Aggr; n = parseint(&p); while(*p != ';'){ name = p; p = findcolon(p)+1; namelen = (p-name)-1; tt = parseinfo(p, &p); comma(&p); offset = parseint(&p); comma(&p); bits = parseint(&p); semi(&p); if(t->n%32 == 0){ t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0])); t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0])); t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0])); } t->tname[t->n] = estrndup(name, namelen); t->val[t->n] = offset; t->t[t->n] = tt; t->n++; } semi(&p); break; case 'x': /* struct, union, enum reference */ p++; t->ty = Defer; if(*p != 's' && *p != 'u' && *p != 'e') oops(); c = *p; name = p+1; p = findcolon(p+1); name = estrndup(name, p-name); t->sub = typebysue(c, name); p++; break; #if 0 /* AIX */ case 'f': /* function */ case 'p': /* procedure */ case 'F': /* Pascal function */ /* case 'R': /* Pascal procedure */ /* * Even though we don't use the info, we have * to parse it in case it is embedded in other descriptions. */ t->ty = Function; p++; if(c == 'f' || c == 'F'){ t->sub = parseinfo(p, &p); if(*p != ','){ if(*p == ';') p++; break; } comma(&p); } n = parseint(&p); /* number of params */ semi(&p); while(*p != ';'){ if(c == 'F' || c == 'R'){ name = p; /* parameter name */ p = findcolon(p)+1; } parseinfo(p, &p); /* param type */ comma(&p); parseint(&p); /* bool: passed by value? */ semi(&p); } semi(&p); break; #endif case 'f': /* static function */ case 'F': /* global function */ t->ty = Function; p++; t->sub = parseinfo(p, &p); break; /* * We'll never see any of this stuff. * When we do, we can worry about it. */ case 'D': /* n-dimensional array */ case 'E': /* subarray of n-dimensional array */ case 'M': /* fortran multiple instance type */ case 'N': /* pascal string ptr */ case 'S': /* set */ case 'c': /* aix complex */ case 'd': /* file of */ case 'g': /* aix float */ case 'n': /* max length string */ case 'w': /* aix wide char */ case 'z': /* another max length string */ default: fprint(2, "unsupported type char %c (%d)\n", *p, *p); oops(); } *pp = p; return t; }
int main(int argc, char** argv) { // between ok(between('a','z','c'), "c is between a and z"); fail(between('a','z','C'), "C is not between a and z"); // num ok(num('0'), "0 is a number"); ok(num('9'), "9 is a number"); fail(num('/'), "/ is not a number"); fail(num(':'), "0 is not a number"); // alpha ok(alpha('a'), "a is a letter"); ok(alpha('z'), "z is a letter"); ok(alpha('A'), "A is a letter"); ok(alpha('Z'), "Z is a letter"); fail(alpha('@'), "@ is not a letter"); fail(alpha('['), "[ is not a letter"); fail(alpha('`'), "` is not a letter"); fail(alpha('{'), "{ is not a letter"); // alphanum ok(alphanum('a'), "a is alphanum"); ok(alphanum('z'), "z is alphanum"); ok(alphanum('A'), "A is alphanum"); ok(alphanum('Z'), "Z is alphanum"); ok(alphanum('0'), "0 is alphanum"); ok(alphanum('9'), "9 is alphanum"); fail(alpha('@'), "@ is not alphanum "); fail(alpha('['), "[ is not alphanum"); fail(alpha('`'), "` is not alphanum"); fail(alpha('{'), "{ is not alphanum"); // space ok(space(' '), "space is space"); fail(space('\n'), "new line is not space"); fail(space('\r'), "cr is not space"); fail(space('\t'), "tab is not space"); // tab ok(tab('\t'), "tab is tab"); fail(tab(' '), "space is not tab"); fail(tab('\n'), "new line is not tab"); fail(tab('\r'), "cr is not tab"); // nl ok(nl('\n'), "new line is new line"); fail(nl('\t'), "tab is not new line"); fail(nl(' '), "space is not new line"); fail(nl('\r'), "cr is not new line"); // cr fail(cr('\n'), "new line is not cr"); fail(cr('\t'), "tab is not cr"); fail(cr(' '), "space is not cr"); ok(cr('\r'), "cr is cr"); // whitespace ok(whitespace('\n'), "new line is whitespace"); ok(whitespace('\t'), "tab is whitespace"); ok(whitespace(' '), "space is whitespace"); ok(whitespace('\r'), "cr is whitespace"); fail(whitespace('\b'), "backspace is not whitespace"); // colon ok(colon(':'), "colon is colon"); fail(colon(';'), "semicolon is not colon"); // semi fail(semi(':'), "colon is not semicolon"); ok(semi(';'), "semicolon is semicolon"); // slash fail(slash('\\'), "\\ is not /"); ok(slash('/'), "/ is /"); // dot fail(dot('*'), "* is not ."); ok(dot('.'), ". is ."); // star ok(star('*'), "* is *"); fail(star('.'), ". is not *"); // question ok(question('?'), "? is ?"); // hex ok(hex('a'), "a is hex"); ok(hex('f'), "f is hex"); ok(hex('A'), "A is hex"); ok(hex('F'), "F is hex"); ok(hex('0'), "0 is hex"); ok(hex('9'), "9 is hex"); fail(hex('g'), "g is not hex"); fail(hex('G'), "G is not hex"); // decimal ok(decimal('0'), "0 is decimal"); ok(decimal('9'), "9 is decimal"); ok(decimal('.'), ". is decimal"); fail(decimal('a'), "a is not decimal"); // ctrl ok(ctrl('\b'), "Backspace is ctrl"); ok(ctrl('\a'), "Bell is ctrl"); ok(ctrl(127), "Del is ctrl"); fail(ctrl('a'), "a is not ctrl"); // any value(3,any(alpha,"abc123"), "three letters at abc123"); value(0,any(num,"abc123"), "no numbers at abc123"); value(6,any(alphanum,"abc123"), "six alphanum in abc123"); // until value(5,until(space,"hello world!"), "5 letters until space"); value(11,until(question,"hello world?"), "11 letters until question"); value(12,until(ctrl,"hello world?"), "12 chacters till end"); // crlf, eol, and upto value(6, upto(eol, "line 1\r\nline 1\r\n"), "6 chars upto crlf"); value(0, upto(eol, "\r\n\r\n"), "0 characters to end of line"); value(12, upto(eol, "hello world!"), "12 characters to eol"); // all test value(5, all(dot, ".....\r\n"), "there are 5 dots"); return done("test_parse"); }
static void continue_stmt(void) { Token = scan(); if (!Csp) error("'continue' not in loop context", NULL); genjump(Contstk[Csp-1]); semi(); }
static void break_stmt(void) { Token = scan(); if (!Bsp) error("'break' not in loop/switch context", NULL); genjump(Breakstk[Bsp-1]); semi(); }
void NetworkConfig::_fromDictionary(const Dictionary &d) { static const std::string zero("0"); static const std::string one("1"); // NOTE: d.get(name) throws if not found, d.get(name,default) returns default _nwid = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID).c_str()); if (!_nwid) throw std::invalid_argument("configuration contains zero network ID"); _timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP).c_str()); _revision = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_REVISION,"1").c_str()); // older controllers don't send this, so default to 1 memset(_etWhitelist,0,sizeof(_etWhitelist)); std::vector<std::string> ets(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES).c_str(),",","","")); for(std::vector<std::string>::const_iterator et(ets.begin());et!=ets.end();++et) { unsigned int tmp = Utils::hexStrToUInt(et->c_str()) & 0xffff; _etWhitelist[tmp >> 3] |= (1 << (tmp & 7)); } _issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO)); _multicastLimit = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,zero).c_str()); if (_multicastLimit == 0) _multicastLimit = ZT_MULTICAST_DEFAULT_LIMIT; _allowPassiveBridging = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING,zero).c_str()) != 0); _private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0); _enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0); _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME); if (_name.length() > ZT1_MAX_NETWORK_SHORT_NAME_LENGTH) throw std::invalid_argument("network short name too long (max: 255 characters)"); _description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string()); // In dictionary IPs are split into V4 and V6 addresses, but we don't really // need that so merge them here. std::string ipAddrs(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC,std::string())); { std::string v6s(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC,std::string())); if (v6s.length()) { if (ipAddrs.length()) ipAddrs.push_back(','); ipAddrs.append(v6s); } } std::vector<std::string> ipAddrsSplit(Utils::split(ipAddrs.c_str(),",","","")); for(std::vector<std::string>::const_iterator ipstr(ipAddrsSplit.begin());ipstr!=ipAddrsSplit.end();++ipstr) { InetAddress addr(*ipstr); switch(addr.ss_family) { case AF_INET: if ((!addr.netmaskBits())||(addr.netmaskBits() > 32)) continue; break; case AF_INET6: if ((!addr.netmaskBits())||(addr.netmaskBits() > 128)) continue; break; default: // ignore unrecognized address types or junk/empty fields continue; } _staticIps.push_back(addr); } if (_staticIps.size() > ZT1_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned IP addresses"); std::sort(_staticIps.begin(),_staticIps.end()); std::unique(_staticIps.begin(),_staticIps.end()); std::vector<std::string> activeBridgesSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES,"").c_str(),",","","")); for(std::vector<std::string>::const_iterator a(activeBridgesSplit.begin());a!=activeBridgesSplit.end();++a) { if (a->length() == ZT_ADDRESS_LENGTH_HEX) { // ignore empty or garbage fields Address tmp(*a); if (!tmp.isReserved()) _activeBridges.push_back(tmp); } } std::sort(_activeBridges.begin(),_activeBridges.end()); std::unique(_activeBridges.begin(),_activeBridges.end()); Dictionary multicastRateEntries(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES,std::string())); for(Dictionary::const_iterator i(multicastRateEntries.begin());i!=multicastRateEntries.end();++i) { std::vector<std::string> params(Utils::split(i->second.c_str(),",","","")); if (params.size() >= 3) _multicastRates[MulticastGroup(i->first)] = MulticastRate(Utils::hexStrToUInt(params[0].c_str()),Utils::hexStrToUInt(params[1].c_str()),Utils::hexStrToUInt(params[2].c_str())); } std::vector<std::string> relaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_RELAYS,"").c_str(),",","","")); for(std::vector<std::string>::const_iterator r(relaysSplit.begin());r!=relaysSplit.end();++r) { std::size_t semi(r->find(';')); // address;ip/port,... if (semi == ZT_ADDRESS_LENGTH_HEX) { std::pair<Address,InetAddress> relay( Address(r->substr(0,semi)), ((r->length() > (semi + 1)) ? InetAddress(r->substr(semi + 1)) : InetAddress()) ); if ((relay.first)&&(!relay.first.isReserved())) _relays.push_back(relay); } } std::sort(_relays.begin(),_relays.end()); std::unique(_relays.begin(),_relays.end()); _com.fromString(d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP,std::string())); }