map_location::DIRECTION map_location::parse_direction(const std::string& str) { if(str.empty()) { return NDIRECTIONS; } // Syntax: [-] (n|ne|se|s|sw|nw) [:cw|:ccw] // - means "take opposite direction" and has higher precedence // :cw and :ccw mean "one step (counter-)clockwise" // Parentheses can be used for grouping or to apply an operator more than once const size_t open = str.find_first_of('('), close = str.find_last_of(')'); if (open != std::string::npos && close != std::string::npos) { std::string sub = str.substr(open + 1, close - open - 1); map_location::DIRECTION dir = parse_direction(sub); sub = str; sub.replace(open, close - open + 1, write_direction(dir)); return parse_direction(sub); } const size_t start = str[0] == '-' ? 1 : 0; const size_t end = str.find_first_of(':'); const std::string& main_dir = str.substr(start, end - start); map_location::DIRECTION dir; if (main_dir == "n") { dir = NORTH; } else if (main_dir == "ne") { dir = NORTH_EAST; } else if (main_dir == "se") { dir = SOUTH_EAST; } else if (main_dir == "s") { dir = SOUTH; } else if (main_dir == "sw") { dir = SOUTH_WEST; } else if (main_dir == "nw") { dir = NORTH_WEST; } else { return NDIRECTIONS; } if (start == 1) { dir = get_opposite_dir(dir); } if (end != std::string::npos) { const std::string rel_dir = str.substr(end + 1); if (rel_dir == "cw") { dir = rotate_right(dir, 1); } else if (rel_dir == "ccw") { dir = rotate_right(dir, -1); } else { return NDIRECTIONS; } } return dir; }
void FlexFlowPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser) { auto &tokens = parser.tokens; size_t pos = 0; StyleToken token = next_token(pos, tokens); StyleSetValue direction = StyleSetValue::from_keyword("row"); StyleSetValue wrap = StyleSetValue::from_keyword("nowrap"); bool direction_specified = false; bool wrap_specified = false; do { if (!direction_specified && parse_direction(direction, pos, tokens)) { direction_specified = true; } else if (!wrap_specified && parse_wrap(wrap, pos, tokens)) { wrap_specified = true; } else { return; } } while (pos != tokens.size()); setter->set_value("flex-direction", direction); setter->set_value("flex-wrap", wrap); }
void RouteParser::element_open_actions() { if (!substring.compare("route")) { parse_route(); } else if (!substring.compare("stop")) { parse_stop(); } else if (!substring.compare("direction")) { parse_direction(); } }
int main(int argc, char **argv) { FILE* fp; // file pointer to input file char move = '\0'; // character depicting next move int direction[2]; // direction of the move in cartesian plane Position* head = NULL; // head of set (linked list) Position santa_position; // current santa position santa_position.x = 0; santa_position.y = 0; Position robot_position; // current robot position robot_position.x = 0; robot_position.y = 0; mark_position_visited(&head, santa_position); // Since Santa goes first, // Robot would have been the one before that. // Current member will hold whoever is moving currently. Position* current_member = &robot_position; fp = fopen("./input.txt", "r"); // Read the file one character at a time while((move=fgetc(fp)) != EOF) { // Get the next move parse_direction(move, direction); // Get position of currently active member current_member = switcher(current_member, &santa_position, &robot_position); // Add the next move to current position current_member->x += direction[0]; current_member->y += direction[1]; // Check if position has been previously visited. // If it hasn't been, mark it as visited. if (!position_was_visited(head, *current_member)) { mark_position_visited(&head, *current_member); } } printf("%ld\n", list_length(head)); // Free the list and close the file. clear_memory(&head); fclose(fp); return 0; }
/** * Load avatar sprite layer definitions into vector. */ void Avatar::loadLayerDefinitions() { layer_def = std::vector<std::vector<unsigned> >(8, std::vector<unsigned>()); layer_reference_order = std::vector<std::string>(); FileParser infile; // @CLASS Avatar: Hero layers|Description of engine/hero_layers.txt if (infile.open("engine/hero_layers.txt")) { while(infile.next()) { if (infile.key == "layer") { // @ATTR layer|direction, list(string) : Direction, Layer name(s)|Defines the hero avatar sprite layer unsigned dir = parse_direction(popFirstString(infile.val)); if (dir>7) { infile.error("Avatar: Hero layer direction must be in range [0,7]"); Exit(1); } std::string layer = popFirstString(infile.val); while (layer != "") { // check if already in layer_reference: unsigned ref_pos; for (ref_pos = 0; ref_pos < layer_reference_order.size(); ++ref_pos) if (layer == layer_reference_order[ref_pos]) break; if (ref_pos == layer_reference_order.size()) layer_reference_order.push_back(layer); layer_def[dir].push_back(ref_pos); layer = popFirstString(infile.val); } } else { infile.error("Avatar: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // There are the positions of the items relative to layer_reference_order // so if layer_reference_order=main,body,head,off // and we got a layer=3,off,body,head,main // then the layer_def[3] looks like (3,1,2,0) }
static int parse_mirred(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) { int argc = *argc_p; char **argv = *argv_p; if (argc < 0) { fprintf(stderr, "mirred bad argument count %d\n", argc); return -1; } if (matches(*argv, "mirred") == 0) { NEXT_ARG(); } else { fprintf(stderr, "mirred bad argument %s\n", *argv); return -1; } if (matches(*argv, "egress") == 0 || matches(*argv, "ingress") == 0 || matches(*argv, "index") == 0) { int ret = parse_direction(a, &argc, &argv, tca_id, n); if (ret == 0) { *argc_p = argc; *argv_p = argv; return 0; } } else if (matches(*argv, "help") == 0) { usage(); } else { fprintf(stderr, "mirred option not supported %s\n", *argv); } return -1; }
map_location::DIRECTION map_location::parse_direction(const std::string& str) { if(!str.empty()) { if(str == "n") { return NORTH; } else if(str == "ne") { return NORTH_EAST; } else if(str == "se") { return SOUTH_EAST; } else if(str == "s") { return SOUTH; } else if(str == "sw") { return SOUTH_WEST; } else if(str == "nw") { return NORTH_WEST; } else if(str[0] == '-' && str.length() <= 10) { // A minus sign reverses the direction return get_opposite_dir(parse_direction(str.substr(1))); } } return NDIRECTIONS; }
void Map::loadEnemyGroup(FileParser &infile, Map_Group *group) { if (infile.key == "type") { // @ATTR enemygroup.type|string|The category of enemies that will spawn in this group. group->category = infile.val; } else if (infile.key == "level") { // @ATTR enemygroup.level|[min(integer), max(integer)]|Defines the level range of enemies in group. If only one number is given, it's the exact level. group->levelmin = std::max(0, toInt(infile.nextValue())); group->levelmax = std::max(0, toInt(infile.nextValue(), group->levelmin)); } else if (infile.key == "location") { // @ATTR enemygroup.location|[x(integer), y(integer), x2(integer), y2(integer)]|Location area for enemygroup group->pos.x = toInt(infile.nextValue()); group->pos.y = toInt(infile.nextValue()); group->area.x = toInt(infile.nextValue()); group->area.y = toInt(infile.nextValue()); } else if (infile.key == "number") { // @ATTR enemygroup.number|[min(integer), max(integer]|Defines the range of enemies in group. If only one number is given, it's the exact amount. group->numbermin = std::max(0, toInt(infile.nextValue())); group->numbermax = std::max(0, toInt(infile.nextValue(), group->numbermin)); } else if (infile.key == "chance") { // @ATTR enemygroup.chance|integer|Percentage of chance float n = static_cast<float>(std::max(0, toInt(infile.nextValue()))) / 100.0f; group->chance = std::min(1.0f, std::max(0.0f, n)); } else if (infile.key == "direction") { // @ATTR enemygroup.direction|direction|Direction that enemies will initially face. group->direction = parse_direction(infile.val); } else if (infile.key == "waypoints") { // @ATTR enemygroup.waypoints|[x(integer), y(integer)]|Enemy waypoints; single enemy only; negates wander_radius std::string none = ""; std::string a = infile.nextValue(); std::string b = infile.nextValue(); while (a != none) { FPoint p; p.x = static_cast<float>(toInt(a)) + 0.5f; p.y = static_cast<float>(toInt(b)) + 0.5f; group->waypoints.push(p); a = infile.nextValue(); b = infile.nextValue(); } // disable wander radius, since we can't have waypoints and wandering at the same time group->wander_radius = 0; } else if (infile.key == "wander_radius") { // @ATTR enemygroup.wander_radius|integer|The radius (in tiles) that an enemy will wander around randomly; negates waypoints group->wander_radius = std::max(0, toInt(infile.nextValue())); // clear waypoints, since wandering will use the waypoint queue while (!group->waypoints.empty()) { group->waypoints.pop(); } } else if (infile.key == "requires_status") { // @ATTR enemygroup.requires_status|string|Status required for loading enemies group->requires_status.push_back(infile.nextValue()); } else if (infile.key == "requires_not_status") { // @ATTR enemygroup.requires_not_status|string|Status required to be missing for loading enemies group->requires_not_status.push_back(infile.nextValue()); } else { infile.error("Map: '%s' is not a valid key.", infile.key.c_str()); } }
static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_policy_info *info = (void *)(*match)->data; struct ipt_policy_elem *e = &info->pol[info->len]; struct in_addr *addr = NULL, mask; unsigned int naddr = 0; int mode; check_inverse(optarg, &invert, &optind, 0); switch (c) { case '1': if (info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT)) exit_error(PARAMETER_PROBLEM, "policy match: double --dir option"); if (invert) exit_error(PARAMETER_PROBLEM, "policy match: can't invert --dir option"); info->flags |= parse_direction(argv[optind-1]); break; case '2': if (invert) exit_error(PARAMETER_PROBLEM, "policy match: can't invert --policy option"); info->flags |= parse_policy(argv[optind-1]); break; case '3': if (info->flags & IPT_POLICY_MATCH_STRICT) exit_error(PARAMETER_PROBLEM, "policy match: double --strict option"); if (invert) exit_error(PARAMETER_PROBLEM, "policy match: can't invert --strict option"); info->flags |= IPT_POLICY_MATCH_STRICT; break; case '4': if (e->match.reqid) exit_error(PARAMETER_PROBLEM, "policy match: double --reqid option"); e->match.reqid = 1; e->invert.reqid = invert; e->reqid = strtol(argv[optind-1], NULL, 10); break; case '5': if (e->match.spi) exit_error(PARAMETER_PROBLEM, "policy match: double --spi option"); e->match.spi = 1; e->invert.spi = invert; e->spi = strtol(argv[optind-1], NULL, 0x10); break; case '6': if (e->match.saddr) exit_error(PARAMETER_PROBLEM, "policy match: double --tunnel-src option"); parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr); if (naddr > 1) exit_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.saddr = 1; e->invert.saddr = invert; e->saddr.a4 = addr[0]; e->smask.a4 = mask; break; case '7': if (e->match.daddr) exit_error(PARAMETER_PROBLEM, "policy match: double --tunnel-dst option"); parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr); if (naddr > 1) exit_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.daddr = 1; e->invert.daddr = invert; e->daddr.a4 = addr[0]; e->dmask.a4 = mask; break; case '8': if (e->match.proto) exit_error(PARAMETER_PROBLEM, "policy match: double --proto option"); e->proto = parse_protocol(argv[optind-1]); if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP && e->proto != IPPROTO_COMP) exit_error(PARAMETER_PROBLEM, "policy match: protocol must ah/esp/ipcomp"); e->match.proto = 1; e->invert.proto = invert; break; case '9': if (e->match.mode) exit_error(PARAMETER_PROBLEM, "policy match: double --mode option"); mode = parse_mode(argv[optind-1]); e->match.mode = 1; e->invert.mode = invert; e->mode = mode; break; case 'a': if (invert) exit_error(PARAMETER_PROBLEM, "policy match: can't invert --next option"); if (++info->len == IPT_POLICY_MAX_ELEM) exit_error(PARAMETER_PROBLEM, "policy match: maximum policy depth reached"); break; default: return 0; } policy_info = info; return 1; }
/** * NPCs are stored in simple config files * * @param npc_id Config file for npc */ void NPC::load(const std::string& npc_id) { FileParser infile; ItemStack stack; portrait_filenames.resize(1); // @CLASS NPC|Description of NPCs in npcs/ if (infile.open(npc_id)) { bool clear_random_table = true; while (infile.next()) { if (infile.section == "dialog") { if (infile.new_section) { dialog.push_back(std::vector<Event_Component>()); } Event_Component e; e.type = EC_NONE; if (infile.key == "him" || infile.key == "her") { // @ATTR dialog.him|repeatable(string)|A line of dialog from the NPC. // @ATTR dialog.her|repeatable(string)|A line of dialog from the NPC. e.type = EC_NPC_DIALOG_THEM; e.s = msg->get(infile.val); } else if (infile.key == "you") { // @ATTR dialog.you|repeatable(string)|A line of dialog from the player. e.type = EC_NPC_DIALOG_YOU; e.s = msg->get(infile.val); } else if (infile.key == "voice") { // @ATTR dialog.voice|repeatable(string)|Filename of a voice sound file to play. e.type = EC_NPC_VOICE; e.x = loadSound(infile.val, NPC_VOX_QUEST); } else if (infile.key == "topic") { // @ATTR dialog.topic|string|The name of this dialog topic. Displayed when picking a dialog tree. e.type = EC_NPC_DIALOG_TOPIC; e.s = msg->get(infile.val); } else if (infile.key == "group") { // @ATTR dialog.group|string|Dialog group. e.type = EC_NPC_DIALOG_GROUP; e.s = infile.val; } else if (infile.key == "allow_movement") { // @ATTR dialog.allow_movement|bool|Restrict the player's mvoement during dialog. e.type = EC_NPC_ALLOW_MOVEMENT; e.s = infile.val; } else if (infile.key == "portrait_him" || infile.key == "portrait_her") { // @ATTR dialog.portrait_him|repeatable(filename)|Filename of a portrait to display for the NPC during this dialog. // @ATTR dialog.portrait_her|repeatable(filename)|Filename of a portrait to display for the NPC during this dialog. e.type = EC_NPC_PORTRAIT_THEM; e.s = infile.val; portrait_filenames.push_back(e.s); } else if (infile.key == "portrait_you") { // @ATTR dialog.portrait_you|repeatable(filename)|Filename of a portrait to display for the player during this dialog. e.type = EC_NPC_PORTRAIT_YOU; e.s = infile.val; portrait_filenames.push_back(e.s); } else { Event ev; EventManager::loadEventComponent(infile, &ev, NULL); for (size_t i=0; i<ev.components.size(); ++i) { if (ev.components[i].type != EC_NONE) { dialog.back().push_back(ev.components[i]); } } } if (e.type != EC_NONE) { dialog.back().push_back(e); } } else { filename = npc_id; if (infile.new_section) { // APPENDed file clear_random_table = true; } if (infile.key == "name") { // @ATTR name|string|NPC's name. name = msg->get(infile.val); } else if (infile.key == "gfx") { // @ATTR gfx|filename|Filename of an animation definition. gfx = infile.val; } else if (infile.key == "direction") { // @ATTR direction|direction|The direction to use for this NPC's stance animation. direction = parse_direction(infile.val); } // handle talkers else if (infile.key == "talker") { // @ATTR talker|bool|Allows this NPC to be talked to. talker = toBool(infile.val); } else if (infile.key == "portrait") { // @ATTR portrait|filename|Filename of the default portrait image. portrait_filenames[0] = infile.val; } // handle vendors else if (infile.key == "vendor") { // @ATTR vendor|bool|Allows this NPC to buy/sell items. vendor = toBool(infile.val); } else if (infile.key == "vendor_requires_status") { // @ATTR vendor_requires_status|list(string)|The player must have these statuses in order to use this NPC as a vendor. while (infile.val != "") { vendor_requires_status.push_back(popFirstString(infile.val)); } } else if (infile.key == "vendor_requires_not_status") { // @ATTR vendor_requires_not_status|list(string)|The player must not have these statuses in order to use this NPC as a vendor. while (infile.val != "") { vendor_requires_not_status.push_back(popFirstString(infile.val)); } } else if (infile.key == "constant_stock") { // @ATTR constant_stock|repeatable(list(item_id))|A list of items this vendor has for sale. stack.quantity = 1; while (infile.val != "") { stack.item = popFirstInt(infile.val); stock.add(stack); } } else if (infile.key == "status_stock") { // @ATTR status_stock|repeatable(string, list(item_id)) : Required status, Item(s)|A list of items this vendor will have for sale if the required status is met. if (camp->checkStatus(popFirstString(infile.val))) { stack.quantity = 1; while (infile.val != "") { stack.item = popFirstInt(infile.val); stock.add(stack); } } } else if (infile.key == "random_stock") { // @ATTR random_stock|list(loot)|Use a loot table to add random items to the stock; either a filename or an inline definition. if (clear_random_table) { random_table.clear(); clear_random_table = false; } random_table.push_back(Event_Component()); loot->parseLoot(infile.val, &random_table.back(), &random_table); } else if (infile.key == "random_stock_count") { // @ATTR random_stock_count|int, int : Min, Max|Sets the minimum (and optionally, the maximum) amount of random items this npc can have. random_table_count.x = popFirstInt(infile.val); random_table_count.y = popFirstInt(infile.val); if (random_table_count.x != 0 || random_table_count.y != 0) { random_table_count.x = std::max(random_table_count.x, 1); random_table_count.y = std::max(random_table_count.y, random_table_count.x); } } // handle vocals else if (infile.key == "vox_intro") { // @ATTR vox_intro|repeatable(filename)|Filename of a sound file to play when initially interacting with the NPC. loadSound(infile.val, NPC_VOX_INTRO); } else { infile.error("NPC: '%s' is not a valid key.", infile.key.c_str()); } } } infile.close(); } loadGraphics(); // fill inventory with items from random stock table unsigned rand_count = randBetween(random_table_count.x, random_table_count.y); std::vector<ItemStack> rand_itemstacks; for (unsigned i=0; i<rand_count; ++i) { loot->checkLoot(random_table, NULL, &rand_itemstacks); } std::sort(rand_itemstacks.begin(), rand_itemstacks.end(), compareItemStack); for (size_t i=0; i<rand_itemstacks.size(); ++i) { stock.add(rand_itemstacks[i]); } }
void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd) { monitor_t *m = mon; desktop_t *d = mon->desk; node_t *f = mon->desk->focus; parse_rule_consequence(fd, csq); if (!csq->manage) { free(csq->layer); free(csq->state); window_show(win); return; } if (csq->node_desc[0] != '\0') { coordinates_t ref = {m, d, f}; coordinates_t trg = {NULL, NULL, NULL}; if (node_from_desc(csq->node_desc, &ref, &trg)) { m = trg.monitor; d = trg.desktop; f = trg.node; } } else if (csq->desktop_desc[0] != '\0') { coordinates_t ref = {m, d, NULL}; coordinates_t trg = {NULL, NULL, NULL}; if (desktop_from_desc(csq->desktop_desc, &ref, &trg)) { m = trg.monitor; d = trg.desktop; f = trg.desktop->focus; } } else if (csq->monitor_desc[0] != '\0') { coordinates_t ref = {m, NULL, NULL}; coordinates_t trg = {NULL, NULL, NULL}; if (monitor_from_desc(csq->monitor_desc, &ref, &trg)) { m = trg.monitor; d = trg.monitor->desk; f = trg.monitor->desk->focus; } } if (csq->sticky) { m = mon; d = mon->desk; f = mon->desk->focus; } if (csq->split_dir[0] != '\0' && f != NULL) { direction_t dir; if (parse_direction(csq->split_dir, &dir)) { presel_dir(m, d, f, dir); } } if (csq->split_ratio != 0 && f != NULL) { presel_ratio(m, d, f, csq->split_ratio); } node_t *n = make_node(win); client_t *c = make_client(); c->border_width = csq->border ? d->border_width : 0; n->client = c; initialize_client(n); update_floating_rectangle(n); if (c->floating_rectangle.x == 0 && c->floating_rectangle.y == 0) { csq->center = true; } c->min_width = csq->min_width; c->max_width = csq->max_width; c->min_height = csq->min_height; c->max_height = csq->max_height; monitor_t *mm = monitor_from_client(c); embrace_client(mm, c); adapt_geometry(&mm->rectangle, &m->rectangle, n); if (csq->center) { window_center(m, c); } snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name); snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name); f = insert_node(m, d, n, f); clients_count++; put_status(SBSC_MASK_NODE_MANAGE, "node_manage %s %s 0x%X 0x%X\n", m->name, d->name, win, f!=NULL?f->id:0); if (f != NULL && f->client != NULL && csq->state != NULL && *(csq->state) == STATE_FLOATING) { c->last_layer = c->layer = f->client->layer; } if (csq->layer != NULL) { c->last_layer = c->layer = *(csq->layer); } if (csq->state != NULL) { set_state(m, d, n, *(csq->state)); c->last_state = c->state; } set_locked(m, d, n, csq->locked); set_sticky(m, d, n, csq->sticky); set_private(m, d, n, csq->private); arrange(m, d); bool give_focus = (csq->focus && (d == mon->desk || csq->follow)); if (give_focus) { focus_node(m, d, n); } else if (csq->focus) { activate_node(m, d, n); } else { stack(d, n, false); } uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)}; xcb_change_window_attributes(dpy, win, XCB_CW_EVENT_MASK, values); if (d == m->desk) { window_show(n->id); } else { window_hide(n->id); } /* the same function is already called in `focus_node` but has no effects on unmapped windows */ if (give_focus) { xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME); } ewmh_set_wm_desktop(n, d); ewmh_update_client_list(false); free(csq->layer); free(csq->state); }
void Map::loadEnemyGroup(FileParser &infile, Map_Group *group) { if (infile.key == "type") { // @ATTR enemygroup.type|string|(IGNORED BY ENGINE) The "type" field, as used by Tiled and other mapping tools. group->type = infile.val; } else if (infile.key == "category") { // @ATTR enemygroup.category|predefined_string|The category of enemies that will spawn in this group. group->category = infile.val; } else if (infile.key == "level") { // @ATTR enemygroup.level|int, int : Min, Max|Defines the level range of enemies in group. If only one number is given, it's the exact level. group->levelmin = std::max(0, popFirstInt(infile.val)); group->levelmax = std::max(std::max(0, toInt(popFirstString(infile.val))), group->levelmin); } else if (infile.key == "location") { // @ATTR enemygroup.location|rectangle|Location area for enemygroup group->pos.x = popFirstInt(infile.val); group->pos.y = popFirstInt(infile.val); group->area.x = popFirstInt(infile.val); group->area.y = popFirstInt(infile.val); } else if (infile.key == "number") { // @ATTR enemygroup.number|int, int : Min, Max|Defines the range of enemies in group. If only one number is given, it's the exact amount. group->numbermin = std::max(0, popFirstInt(infile.val)); group->numbermax = std::max(std::max(0, toInt(popFirstString(infile.val))), group->numbermin); } else if (infile.key == "chance") { // @ATTR enemygroup.chance|int|Percentage of chance float n = static_cast<float>(std::max(0, popFirstInt(infile.val))) / 100.0f; group->chance = std::min(1.0f, std::max(0.0f, n)); } else if (infile.key == "direction") { // @ATTR enemygroup.direction|direction|Direction that enemies will initially face. group->direction = parse_direction(infile.val); } else if (infile.key == "waypoints") { // @ATTR enemygroup.waypoints|list(point)|Enemy waypoints; single enemy only; negates wander_radius std::string none = ""; std::string a = popFirstString(infile.val); std::string b = popFirstString(infile.val); while (a != none) { FPoint p; p.x = static_cast<float>(toInt(a)) + 0.5f; p.y = static_cast<float>(toInt(b)) + 0.5f; group->waypoints.push(p); a = popFirstString(infile.val); b = popFirstString(infile.val); } // disable wander radius, since we can't have waypoints and wandering at the same time group->wander_radius = 0; } else if (infile.key == "wander_radius") { // @ATTR enemygroup.wander_radius|int|The radius (in tiles) that an enemy will wander around randomly; negates waypoints group->wander_radius = std::max(0, popFirstInt(infile.val)); // clear waypoints, since wandering will use the waypoint queue while (!group->waypoints.empty()) { group->waypoints.pop(); } } else if (infile.key == "requires_status") { // @ATTR enemygroup.requires_status|list(string)|Status required for loading enemies std::string s; while ((s = popFirstString(infile.val)) != "") { group->requires_status.push_back(s); } } else if (infile.key == "requires_not_status") { // @ATTR enemygroup.requires_not_status|list(string)|Status required to be missing for loading enemies std::string s; while ((s = popFirstString(infile.val)) != "") { group->requires_not_status.push_back(s); } } else { infile.error("Map: '%s' is not a valid key.", infile.key.c_str()); } }
static int policy_parse(int c, int invert, unsigned int *flags, struct xt_policy_info *info, uint8_t family) { struct xt_policy_elem *e = &info->pol[info->len]; struct in_addr *addr = NULL, mask; struct in6_addr *addr6 = NULL, mask6; unsigned int naddr = 0, num; int mode; xtables_check_inverse(optarg, &invert, &optind, 0); switch (c) { case '1': if (info->flags & (XT_POLICY_MATCH_IN | XT_POLICY_MATCH_OUT)) xtables_error(PARAMETER_PROBLEM, "policy match: double --dir option"); if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --dir option"); info->flags |= parse_direction(optarg); break; case '2': if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --policy option"); info->flags |= parse_policy(optarg); break; case '3': if (info->flags & XT_POLICY_MATCH_STRICT) xtables_error(PARAMETER_PROBLEM, "policy match: double --strict option"); if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --strict option"); info->flags |= XT_POLICY_MATCH_STRICT; break; case '4': if (e->match.reqid) xtables_error(PARAMETER_PROBLEM, "policy match: double --reqid option"); e->match.reqid = 1; e->invert.reqid = invert; if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg); e->reqid = num; break; case '5': if (e->match.spi) xtables_error(PARAMETER_PROBLEM, "policy match: double --spi option"); e->match.spi = 1; e->invert.spi = invert; if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg); e->spi = num; break; case '6': if (e->match.saddr) xtables_error(PARAMETER_PROBLEM, "policy match: double --tunnel-src option"); if (family == NFPROTO_IPV6) xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr); else xtables_ipparse_any(optarg, &addr, &mask, &naddr); if (naddr > 1) xtables_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.saddr = 1; e->invert.saddr = invert; if (family == NFPROTO_IPV6) { memcpy(&e->saddr.a6, addr6, sizeof(*addr6)); memcpy(&e->smask.a6, &mask6, sizeof(mask6)); } else { e->saddr.a4 = addr[0]; e->smask.a4 = mask; } break; case '7': if (e->match.daddr) xtables_error(PARAMETER_PROBLEM, "policy match: double --tunnel-dst option"); if (family == NFPROTO_IPV6) xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr); else xtables_ipparse_any(optarg, &addr, &mask, &naddr); if (naddr > 1) xtables_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.daddr = 1; e->invert.daddr = invert; if (family == NFPROTO_IPV6) { memcpy(&e->daddr.a6, addr6, sizeof(*addr6)); memcpy(&e->dmask.a6, &mask6, sizeof(mask6)); } else { e->daddr.a4 = addr[0]; e->dmask.a4 = mask; } break; case '8': if (e->match.proto) xtables_error(PARAMETER_PROBLEM, "policy match: double --proto option"); e->proto = xtables_parse_protocol(optarg); if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP && e->proto != IPPROTO_COMP) xtables_error(PARAMETER_PROBLEM, "policy match: protocol must ah/esp/ipcomp"); e->match.proto = 1; e->invert.proto = invert; break; case '9': if (e->match.mode) xtables_error(PARAMETER_PROBLEM, "policy match: double --mode option"); mode = parse_mode(optarg); e->match.mode = 1; e->invert.mode = invert; e->mode = mode; break; case 'a': if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --next option"); if (++info->len == XT_POLICY_MAX_ELEM) xtables_error(PARAMETER_PROBLEM, "policy match: maximum policy depth reached"); break; default: return 0; } return 1; }
void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd) { monitor_t *m = mon; desktop_t *d = mon->desk; node_t *f = mon->desk->focus; parse_rule_consequence(fd, csq); if (!csq->manage) { free(csq->layer); free(csq->state); window_show(win); return; } if (csq->node_desc[0] != '\0') { coordinates_t ref = {m, d, f}; coordinates_t trg = {NULL, NULL, NULL}; if (node_from_desc(csq->node_desc, &ref, &trg) == SELECTOR_OK) { m = trg.monitor; d = trg.desktop; f = trg.node; } } else if (csq->desktop_desc[0] != '\0') { coordinates_t ref = {m, d, NULL}; coordinates_t trg = {NULL, NULL, NULL}; if (desktop_from_desc(csq->desktop_desc, &ref, &trg) == SELECTOR_OK) { m = trg.monitor; d = trg.desktop; f = trg.desktop->focus; } } else if (csq->monitor_desc[0] != '\0') { coordinates_t ref = {m, NULL, NULL}; coordinates_t trg = {NULL, NULL, NULL}; if (monitor_from_desc(csq->monitor_desc, &ref, &trg) == SELECTOR_OK) { m = trg.monitor; d = trg.monitor->desk; f = trg.monitor->desk->focus; } } if (csq->sticky) { m = mon; d = mon->desk; f = mon->desk->focus; } if (csq->split_dir[0] != '\0' && f != NULL) { direction_t dir; if (parse_direction(csq->split_dir, &dir)) { presel_dir(m, d, f, dir); } } if (csq->split_ratio != 0 && f != NULL) { presel_ratio(m, d, f, csq->split_ratio); } node_t *n = make_node(win); client_t *c = make_client(); c->border_width = csq->border ? d->border_width : 0; n->client = c; initialize_client(n); initialize_floating_rectangle(n); if (c->floating_rectangle.x == 0 && c->floating_rectangle.y == 0) { csq->center = true; } monitor_t *mm = monitor_from_client(c); embrace_client(mm, c); adapt_geometry(&mm->rectangle, &m->rectangle, n); if (csq->center) { window_center(m, c); } snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name); snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name); f = insert_node(m, d, n, f); clients_count++; put_status(SBSC_MASK_NODE_MANAGE, "node_manage 0x%08X 0x%08X 0x%08X 0x%08X\n", m->id, d->id, win, f!=NULL?f->id:0); if (f != NULL && f->client != NULL && csq->state != NULL && *(csq->state) == STATE_FLOATING) { c->layer = f->client->layer; } if (csq->layer != NULL) { c->layer = *(csq->layer); } if (csq->state != NULL) { set_state(m, d, n, *(csq->state)); } set_hidden(m, d, n, csq->hidden); set_sticky(m, d, n, csq->sticky); set_private(m, d, n, csq->private); set_locked(m, d, n, csq->locked); arrange(m, d); uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)}; xcb_change_window_attributes(dpy, win, XCB_CW_EVENT_MASK, values); if (d == m->desk) { show_node(d, n); } else { hide_node(d, n); } if (!csq->hidden && csq->focus) { if (d == mon->desk || csq->follow) { focus_node(m, d, n); } else { activate_node(m, d, n); } } else { stack(d, n, false); } ewmh_set_wm_desktop(n, d); ewmh_update_client_list(false); free(csq->layer); free(csq->state); }