int max(int col, int player, int depth, int minval) { int i; int bestval; int val; int row; row = is_playable(col) - 1; play(row, col, player); bestval = -100000; if ((!game_is_on()) && depth < get_map()->diff) { i = -1; while (++i < get_map()->width && bestval < minval) { if (is_playable(i)) { val = min(i, player == 1 ? 2 : 1, depth + 1, bestval); bestval = val > bestval ? val : bestval; } } unplay(row, col); return (bestval); } val = get_map_value(); unplay(row, col); return (val); }
bool check_blocked(int x, int y){ if (x >= MAP_WIDTH || x < 0){ return true; } else if (y >= MAP_HEIGHT || y < 0){ return true; } else if (get_map_value(x,y) == 'x'){ return true; } else { return false; } }
MODULE return_url_from_image_map (THREAD *thread) { char *url_map; /* URL for image map */ url_map = get_map_value (request-> filename, request-> arguments); if (url_map) send_wsx_redirect (&thread-> event-> sender, url_map); else send_wsx_error (&thread-> event-> sender, HTTP_RESPONSE_NOTFOUND); }
void draw_world(){ for (int i = 0; i < MAP_WIDTH; ++i){ for (int j = 0; j < MAP_HEIGHT; ++j){ if (NULL != get_sprite_ptr(i,j)){ draw_player(get_sprite_ptr(i,j)); } else { printf("%c ", get_map_value(i,j)); } } printf("\n"); } printf("\n"); }
void MapPack::print_map() { for (int i = 0; i < 32; i++) { for (int j = 0; j < 48; j++) //1,2 = Red, Blue { char buf[2]; int temp; std::string s; std::stringstream out; out << get_map_value(i,j); s = out.str(); cout << "[" << s << "]"; /* if (get_map_value(i,j) == 0) { cout << "[ ]"; } if (get_map_value(i,j) == 1)//Red Squad { cout << "[X]"; } if (get_map_value(i,j) == 2)//Blue Squad { cout << "[Y]"; } if (get_map_value(i,j) == 3)//Wall { cout << "[W]"; } if (get_map_value(i,j) == 4)//Ledge { cout << "[L]"; } if (get_map_value(i,j) > 4 || (get_map_value(i,j) < 0))//Error { cout << "[E]"; } */ if (j == 47) { cout << "\n"; } } } cout << "Board Print SUCCESS\n"; }
void Config_Cache_Scene::refresh_scene_config_cache(void) { PERF_MON("refresh_scene_config_cache"); Relation_Map relation_map; Int_Set scene_set; Scene_Config scene_config; Scene_Config::Transmit_Point_Vec client_find_path_point; const Json::Value json_scene = CONFIG_INSTANCE->config_json()["scene"]["scene_config"]; for (Json::Value::const_iterator it = json_scene.begin(); it != json_scene.end(); it++) { scene_config.reset(); const Json::Value &config = (*it); scene_config.scene_id = config["sceneId"].asInt(); if (config["scene_block"] != Json::Value::null) { if (config["scene_block"].size() != 2) { LOG_ABORT("scene:%d, error scene block", scene_config.scene_id); } scene_config.scene_block_x = config["scene_block"][0u].asInt(); scene_config.scene_block_y = config["scene_block"][1u].asInt(); } const Server_Solution_Cache &server_solution_cache = CONFIG_CACHE->server_solution_cache(); scene_config.order_total = server_solution_cache.fetch_order_total(Server_Enum::MONITOR_TYPE::MONITOR_SCENE, scene_config.scene_id); if (server_solution_cache.inter_server.count(scene_config.scene_id)) scene_config.inter_order = CONFIG_CACHE->server_maintainer_cache().game_inter_flag % scene_config.order_total; scene_config.role_limit = config["role_limit"].asInt(); scene_config.type = Scene_Type(config["type"].asInt()); scene_config.manager = config["manager"].asInt(); if (scene_config.manager == 0 || scene_config.manager >= Scene_Manager_Enum::Scene_Unknow) { LOG_ABORT("scene:%ld 未知manager:%d", scene_config.scene_id, scene_config.manager); } scene_config.map_id = config["mapId"].asInt(); ABORT_INT_ZERO(scene_config.scene_id); ABORT_INT_ZERO(scene_config.map_id); if (scene_set.count(scene_config.scene_id)) LOG_ABORT("场景id重复id:%d", scene_config.scene_id); scene_config.scene_name = config["defaultName"].asString(); scene_config.login_create = config["login_create"].asBool(); scene_config.timeLimit = config["timeLimit"].asInt(); if (config["transmit_point"] != Json::Value::null) { Transmit_Point point; for (Json::Value::const_iterator it = config["transmit_point"].begin(); it != config["transmit_point"].end(); ++it) { Json_Utility::assign_coord((*it)["coord"], point.coord); point.scene_id = scene_config.scene_id; point.visible = (*it)["visible"].asInt(); point.role_name = (*it)["name"].asString(); point.des_scene_id = (*it)["des_scene_id"].asInt(); point.role_id++; int map_value = get_map_value(scene_config.map_id, point.coord); if (map_value <= 0) { LOG_ABORT("传送点坐标非法map id:%d, x:%d, y:%d", scene_config.map_id, point.coord.x, point.coord.y); } scene_config.transmit_point.push_back(point); if ((*it)["client_find_path"].asInt()) client_find_path_point.push_back(point); } } if (config["enter_point"] != Json::Value::null) { for (Json::Value::const_iterator it = config["enter_point"].begin(); it != config["enter_point"].end(); ++it) { Scene_Config::Transmit_Coord coord; Json_Utility::assign_coord((*it)["coord"], coord.coord); coord.src_scene_id = (*it)["src_scene_id"].asInt(); int map_value = get_map_value(scene_config.map_id, coord.coord); if (map_value <= 0) { LOG_ABORT("进入点坐标非法map id:%d, x:%d, y:%d", scene_config.map_id, coord.coord.x, coord.coord.y); } scene_config.transmit_coord.insert(std::make_pair(coord.src_scene_id, coord)); } } if (config["revive_point"] != Json::Value::null) { Coord coord; if (config["revive_point"].size() && config["revive_point"][0u].size() >= 2) { for (uint i = 0; i < config["revive_point"].size(); ++i) { Json_Utility::assign_coord(config["revive_point"][i], coord); int map_value = get_map_value(scene_config.map_id, coord); if (map_value <= 0) { LOG_ABORT("map id:%d, x:%d, y:%d", scene_config.map_id, coord.x, coord.y); } scene_config.revive_point.push_back(coord); } } else { Json_Utility::assign_coord(config["revive_point"], coord); int map_value = get_map_value(scene_config.map_id, coord); if (map_value <= 0) { LOG_ABORT("map id:%d, x:%d, y:%d", scene_config.map_id, coord.x, coord.y); } scene_config.revive_point.push_back(coord); } } if (config["des_scene_limit"] != Json::Value::null) { Json_Utility::assign_set_list(config["des_scene_limit"], scene_config.des_scene_limit); } if (config["scene_keep_time"] != Json::Value::null) { Json_Utility::assign_time_value(config["scene_keep_time"], scene_config.scene_keep_time); } scene_config.hero_disable = config["hero_disable"].asBool(); //dungeon if(config["dungeon"] != Json::Value::null){ const Json::Value &config_json = config["dungeon"]; scene_config.dungeon.reset(); if (config_json.isMember("id")) { scene_config.dungeon.id = config_json["id"].asInt(); } if (config_json.isMember("name")) { scene_config.dungeon.name = config_json["name"].asString(); } if (config_json.isMember("lv")) { scene_config.dungeon.lv = config_json["lv"].asInt(); } if (config_json.isMember("difficulty")) { scene_config.dungeon.difficulty = config_json["difficulty"].asInt(); } if(config_json.isMember("open_con")){ for (Json::Value::iterator s_it = config_json["open_con"].begin(); s_it != config_json["open_con"].end(); ++s_it) { scene_config.dungeon.open_con_map.insert(Scene_Config::Dungeon_Config_Detail::OpenConMap::value_type( (*s_it)[0u].asInt(), (*s_it)[1].asInt())); } } if (config_json.isMember("pass_con")) { scene_config.dungeon.pass_con = config_json["pass_con"].asInt(); } if(config_json.isMember("cost")){ for (Json::Value::iterator s_it = config_json["cost"].begin(); s_it != config_json["cost"].end(); ++s_it) { scene_config.dungeon.cost_map.insert(Scene_Config::Dungeon_Config_Detail::CostMap::value_type( (*s_it)[0u].asInt(), (*s_it)[1].asInt())); } } if (config_json.isMember("entrance")) { scene_config.dungeon.be_enter = config_json["entrance"].asInt(); } if (config_json.isMember("be_mop")) { scene_config.dungeon.be_mop = config_json["be_mop"].asInt(); } if (config_json.isMember("can_team")) { scene_config.dungeon.can_team = config_json["can_team"].asInt(); } if(config_json.isMember("task")){ scene_config.dungeon.require_task = config_json["task"].asInt(); } if (config_json.isMember("team_lim")) { scene_config.dungeon.team_lim = config_json["team_lim"].asInt(); } if (config_json.isMember("relation")) { scene_config.dungeon.relation = config_json["relation"].asInt(); } if (config_json.isMember("next_id")) { scene_config.dungeon.next_id = config_json["next_id"].asInt(); } if (config_json.isMember("elite")) { scene_config.dungeon.elite = config_json["elite"].asInt(); } if (config_json.isMember("vip_exp")) { int vip = 1; Scene_Config::Dungeon_Config_Detail::VipExtMap vipmap; for (Json::Value::iterator s_it = config_json["vip_exp"].begin(); s_it != config_json["vip_exp"].end(); ++s_it) { vipmap.insert(Scene_Config::Dungeon_Config_Detail::VipExtMap::value_type(vip, (*s_it).asInt())); ++vip; } scene_config.dungeon.vip_ext_map = vipmap; } insert_dungeon_relation(relation_map, scene_config.dungeon.relation, scene_config.dungeon.id); scene_config.dungeon.first_layer_id = get_dungeon_first_layer_id(relation_map, scene_config.dungeon.id); // 单人副本和精英副本对应关系 if(scene_config.dungeon.elite != 0){ if(scene_config.dungeon.difficulty == Scene_Config::Dungeon_Config_Detail::DUNGEON_DIFF_NOR){ single_elite_nor_map_.insert(std::make_pair(scene_config.dungeon.elite, scene_config.dungeon.id)); elite_single_map_.insert(std::make_pair(scene_config.dungeon.id,scene_config.dungeon.elite)); }else if(scene_config.dungeon.difficulty == Scene_Config::Dungeon_Config_Detail::DUNGEON_DIFF_HOR){ single_elite_hor_map_.insert(std::make_pair(scene_config.dungeon.elite, scene_config.dungeon.id)); elite_single_map_.insert(std::make_pair(scene_config.dungeon.id,scene_config.dungeon.elite)); } } } scene_set.insert(scene_config.scene_id); set_map_second_value_by_key(scene_config.scene_id, scene_config_cache_map_, scene_config); } client_find_path_point_.reset(); client_find_path_point_.make_message(81000041); uint16_t __transmit_point_vec_size = client_find_path_point.size(); client_find_path_point_.write_uint16(__transmit_point_vec_size); for(uint16_t i = 0; i < __transmit_point_vec_size; ++i) { client_find_path_point[i].serialize(client_find_path_point_); } client_find_path_point_.finish_message(); }
/* * For all x and y as requested, replace the pixel at (x,y) * with a weighted average of the most frequently occurring * values in a circle of mask_size diameter centered at (x,y). */ static void oilify (GimpDrawable *drawable, GimpPreview *preview) { gboolean use_inten; gboolean use_msmap = FALSE; gboolean use_emap = FALSE; GimpDrawable *mask_size_map_drawable = NULL; GimpDrawable *exponent_map_drawable = NULL; GimpPixelRgn mask_size_map_rgn; GimpPixelRgn exponent_map_rgn; gint msmap_bpp = 0; gint emap_bpp = 0; GimpPixelRgn dest_rgn; GimpPixelRgn *regions[3]; gint n_regions; gint bpp; gint *sqr_lut; gint x1, y1, x2, y2; gint width, height; gint Hist[HISTSIZE]; gint Hist_rgb[4][HISTSIZE]; gpointer pr; gint progress, max_progress; guchar *src_buf; guchar *src_inten_buf = NULL; gint i; use_inten = (ovals.mode == MODE_INTEN); /* Get the selection bounds */ if (preview) { gimp_preview_get_position (preview, &x1, &y1); gimp_preview_get_size (preview, &width, &height); x2 = x1 + width; y2 = y1 + height; } else { gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = x2 - x1; height = y2 - y1; } progress = 0; max_progress = width * height; bpp = drawable->bpp; /* * Look-up-table implementation of the square function, for use in the * VERY TIGHT inner loops */ { gint lut_size = (gint) ovals.mask_size / 2 + 1; sqr_lut = g_new (gint, lut_size); for (i = 0; i < lut_size; i++) sqr_lut[i] = SQR (i); } /* Get the map drawables, if applicable */ if (ovals.use_mask_size_map && ovals.mask_size_map >= 0) { use_msmap = TRUE; mask_size_map_drawable = gimp_drawable_get (ovals.mask_size_map); gimp_pixel_rgn_init (&mask_size_map_rgn, mask_size_map_drawable, x1, y1, width, height, FALSE, FALSE); msmap_bpp = mask_size_map_drawable->bpp; } if (ovals.use_exponent_map && ovals.exponent_map >= 0) { use_emap = TRUE; exponent_map_drawable = gimp_drawable_get (ovals.exponent_map); gimp_pixel_rgn_init (&exponent_map_rgn, exponent_map_drawable, x1, y1, width, height, FALSE, FALSE); emap_bpp = exponent_map_drawable->bpp; } gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, width, height, (preview == NULL), TRUE); { GimpPixelRgn src_rgn; gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE); src_buf = g_new (guchar, width * height * bpp); gimp_pixel_rgn_get_rect (&src_rgn, src_buf, x1, y1, width, height); } /* * If we're working in intensity mode, then generate a separate intensity * map of the source image. This way, we can avoid calculating the * intensity of any given source pixel more than once. */ if (use_inten) { guchar *src; guchar *dest; src_inten_buf = g_new (guchar, width * height); for (i = 0, src = src_buf, dest = src_inten_buf ; i < (width * height) ; i++, src += bpp, dest++) { *dest = (guchar) GIMP_RGB_LUMINANCE (src[0], src[1], src[2]); } } n_regions = 0; regions[n_regions++] = &dest_rgn; if (use_msmap) regions[n_regions++] = &mask_size_map_rgn; if (use_emap) regions[n_regions++] = &exponent_map_rgn; for (pr = gimp_pixel_rgns_register2 (n_regions, regions); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { gint y; guchar *dest_row; guchar *src_msmap_row = NULL; guchar *src_emap_row = NULL; for (y = dest_rgn.y, dest_row = dest_rgn.data, src_msmap_row = mask_size_map_rgn.data, /* valid iff use_msmap */ src_emap_row = exponent_map_rgn.data /* valid iff use_emap */ ; y < (gint) (dest_rgn.y + dest_rgn.h) ; y++, dest_row += dest_rgn.rowstride, src_msmap_row += mask_size_map_rgn.rowstride, /* valid iff use_msmap */ src_emap_row += exponent_map_rgn.rowstride) /* valid iff use_emap */ { gint x; guchar *dest; guchar *src_msmap = NULL; guchar *src_emap = NULL; for (x = dest_rgn.x, dest = dest_row, src_msmap = src_msmap_row, /* valid iff use_msmap */ src_emap = src_emap_row /* valid iff use_emap */ ; x < (gint) (dest_rgn.x + dest_rgn.w) ; x++, dest += bpp, src_msmap += msmap_bpp, /* valid iff use_msmap */ src_emap += emap_bpp) /* valid iff use_emap */ { gint radius, radius_squared; gfloat exponent; gint mask_x1, mask_y1; gint mask_x2, mask_y2; gint mask_y; gint src_offset; guchar *src_row; guchar *src_inten_row = NULL; if (use_msmap) { gfloat factor = get_map_value (src_msmap, msmap_bpp); radius = ROUND (factor * (0.5 * ovals.mask_size)); } else { radius = (gint) ovals.mask_size / 2; } radius_squared = SQR (radius); exponent = ovals.exponent; if (use_emap) exponent *= get_map_value (src_emap, emap_bpp); if (use_inten) memset (Hist, 0, sizeof (Hist)); memset (Hist_rgb, 0, sizeof (Hist_rgb)); mask_x1 = CLAMP ((x - radius), x1, x2); mask_y1 = CLAMP ((y - radius), y1, y2); mask_x2 = CLAMP ((x + radius + 1), x1, x2); mask_y2 = CLAMP ((y + radius + 1), y1, y2); src_offset = (mask_y1 - y1) * width + (mask_x1 - x1); for (mask_y = mask_y1, src_row = src_buf + src_offset * bpp, src_inten_row = src_inten_buf + src_offset /* valid iff use_inten */ ; mask_y < mask_y2 ; mask_y++, src_row += width * bpp, src_inten_row += width) /* valid iff use_inten */ { guchar *src; guchar *src_inten = NULL; gint dy_squared = sqr_lut[ABS (mask_y - y)]; gint mask_x; for (mask_x = mask_x1, src = src_row, src_inten = src_inten_row /* valid iff use_inten */ ; mask_x < mask_x2 ; mask_x++, src += bpp, src_inten++) /* valid iff use_inten */ { gint dx_squared = sqr_lut[ABS (mask_x - x)]; gint b; /* Stay inside a circular mask area */ if ((dx_squared + dy_squared) > radius_squared) continue; if (use_inten) { gint inten = *src_inten; ++Hist[inten]; for (b = 0; b < bpp; b++) Hist_rgb[b][inten] += src[b]; } else { for (b = 0; b < bpp; b++) ++Hist_rgb[b][src[b]]; } } /* for mask_x */ } /* for mask_y */ if (use_inten) { weighted_average_color (Hist, Hist_rgb, exponent, dest, bpp); } else { gint b; for (b = 0; b < bpp; b++) dest[b] = weighted_average_value (Hist_rgb[b], exponent); } } /* for x */ } /* for y */ if (preview) { gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview), &dest_rgn); } else { progress += dest_rgn.w * dest_rgn.h; gimp_progress_update ((gdouble) progress / (gdouble) max_progress); } } /* for pr */ /* Detach from the map drawables */ if (mask_size_map_drawable) gimp_drawable_detach (mask_size_map_drawable); if (exponent_map_drawable) gimp_drawable_detach (exponent_map_drawable); if (src_inten_buf) g_free (src_inten_buf); g_free (src_buf); g_free (sqr_lut); if (!preview) { /* Update the oil-painted region */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, width, height); } }
/*-------------------------------------------------------------------------*/ svalue_t * x_filter_string (svalue_t *sp, int num_arg) /* EFUN: filter() for strings. * * string filter(string arr, string fun, string|object obj, mixed extra, ...) * string filter(string arr, closure cl, mixed extra, ...) * string filter(string arr, mapping map) * * Filter the elements of <arr> through a filter defined by the other * arguments, and return an array of those elements, for which the * filter yields non-zero. * * The filter can be a function call: * * <obj>-><fun>(elem, <extra>...) * * or a mapping query: * * <map>[elem] * * <obj> can both be an object reference or a filename. If omitted, * this_object() is used (this also works if the third argument is * neither a string nor an object). */ { string_t *rc; /* Result string */ string_t *str; /* Argument string */ svalue_t *arg; /* First argument the vm stack */ mp_int slen; /* Argument string length */ char *src, *dest; /* String text work pointers */ char *flags; /* Flag array, one flag for each element of <str> * (in reverse order). */ mp_int res; /* Number of surviving elements */ res = 0; /* Locate the args on the stack, extract the string to filter * and allocate the flags vector. */ arg = sp - num_arg + 1; str = arg->u.str; slen = (mp_int)mstrsize(str); /* Every element in flags is associated by index number with an * element in the vector to filter. The filter function is evaluated * for every string character, and the associated flag is set to 0 * or 1 according to the result. * At the end, all 1-flagged elements are gathered and copied * into the result string. */ if (arg[1].type == T_MAPPING) { mp_int cnt; /* --- Filter by mapping query --- */ mapping_t *m; if (num_arg > 2) { errorf("Too many arguments to filter(array)\n"); } /* Allocate memory for the flag array. Simultaneously an error * handler is pushed onto the stack (after the arguments) for freeing * the buffer in case of runtime errors. */ flags = xalloc_with_error_handler((size_t)slen + 1); if (!flags) { errorf("Out of memory (%zu bytes) for temporary buffer in filter().\n", (size_t)slen + 1); } sp = inter_sp; m = arg[1].u.map; for (src = get_txt(str), cnt = slen; --cnt >= 0; src++) { svalue_t key; put_number(&key, *src); if (get_map_value(m, &key) == &const0) { flags[cnt] = 0; continue; } flags[cnt] = 1; res++; } } else { /* --- Filter by function call --- */ int error_index; callback_t cb; mp_int cnt; assign_eval_cost(); /* setup_efun_callback() will adopt and therefore remove the * arguments from arg+1 on to arg+num_arg from the stack and update * inter_sp. New top-of-stack will be arg. */ error_index = setup_efun_callback(&cb, arg+1, num_arg-1); if (error_index >= 0) { vefun_bad_arg(error_index+2, arg); /* NOTREACHED */ return arg; } /* push the callback structure onto the stack. */ sp = arg + 1; put_callback(sp, &cb); /* Allocate memory for the flag array. Simultaneously an error * handler is pushed onto the stack (after the arguments) for freeing * the buffer in case of runtime errors. */ inter_sp = sp; flags = xalloc_with_error_handler((size_t)slen + 1); if (!flags) { errorf("Out of memory (%"PRIdMPINT" bytes) for temporary buffer " "in filter().\n", slen + 1); } sp = inter_sp; /* Loop over all elements in p and call the filter. * w is the current element filtered. */ for (src = get_txt(str), cnt = slen; --cnt >= 0; src++) { svalue_t *v; flags[cnt] = 0; if (current_object->flags & O_DESTRUCTED) continue; /* Don't call the filter anymore, but fill the * flags array with 0es. */ if (!callback_object(&cb)) { inter_sp = sp; errorf("object used by filter(array) destructed"); } push_number(inter_sp, *src); v = apply_callback(&cb, 1); if (!v || (v->type == T_NUMBER && !v->u.number) ) continue; flags[cnt] = 1; res++; } } /* flags[] holds the filter results, res is the number of * elements to keep. Now create the result vector. */ rc = alloc_mstring(res); if (!rc) { errorf("Out of memory (%"PRIdMPINT" bytes) for result in filter().\n", slen+1); } for (src = get_txt(str), dest = get_txt(rc), flags = &flags[slen] ; res > 0 ; src++) { if (*--flags) { *dest++ = *src; res--; } } /* Cleanup. Arguments for the closure have already been removed. On the * stack are now the string, the mapping or callback structure and the * error handler. (Not using pop_n_elems() for 2 elements for saving loop * and function call overhead.) */ free_svalue(sp--); /* errorhandler, buffer and flags are freed by this. */ free_svalue(sp--); /* mapping or callback structure. */ free_mstring(str); /* string, at arg == sp */ sp->u.str = rc; /* put result here */ return sp; } /* x_filter_string() */
/*-------------------------------------------------------------------------*/ svalue_t * x_map_string (svalue_t *sp, int num_arg) /* EFUN map() for strings * * string map(string arg, string func, string|object ob, mixed extra...) * string map(string arg, closure cl, mixed extra...) * string map(string arg, mapping m) * * Call the function <ob>-><func>() resp. the closure <cl> for * every element of the array/struct/mapping/string <arg>, and return a result * made up from the returned values. * * It is also possible to map every entry through a lookup <m>[element]. If * the mapping entry doesn't exist, the original value is kept, otherwise the * result of the mapping lookup. * * Since <arg> is a string, only integer return values are allowed, of which * only the lower 8 bits are considered. * * If <ob> is omitted, or neither an object nor a string, then * this_object() is used. */ { string_t *res; string_t *str; svalue_t *arg; mp_int len; char *src, *dest; inter_sp = sp; arg = sp - num_arg + 1; str = arg->u.str; len = mstrsize(str); if (arg[1].type == T_MAPPING) { /* --- Map through mapping --- */ mapping_t *m; if (num_arg > 2) { inter_sp = sp; errorf("Too many arguments to map(string)\n"); } m = arg[1].u.map; res = alloc_mstring(len); if (!res) errorf("(map_string) Out of memory: string[%"PRIdMPINT "] for result\n", len); push_string(inter_sp, res); /* In case of errors */ for (src = get_txt(str), dest = get_txt(res); --len >= 0; src++, dest++) { svalue_t key, *v; put_number(&key, *src); v = get_map_value(m, &key); if (v == &const0) *dest = *src; else { if (v->type != T_NUMBER) { errorf("(map_string) Illegal value: %s, expected string\n" , typename(v->type) ); } *dest = (v->u.number & 0xFF); } }
/*-------------------------------------------------------------------------*/ svalue_t * x_map_struct (svalue_t *sp, int num_arg) /* EFUN map() on structs * * mixed * map(struct arg, string func, string|object ob, mixed extra...) * mixed * map(struct arg, closure cl, mixed extra...) * mixed * map(struct arr, mapping map [, int col]) * * Map the elements of <arr> through a filter defined by the other * arguments, and return an array of the elements returned by the filter. * * The filter can be a function call: * * <obj>-><fun>(elem, <extra>...) * * or a mapping query: * * <map>[elem[,idx]] * * In the mapping case, if <map>[elem[,idx]] does not exist, the original * value is returned in the result. * [Note: argument type and range checking for idx is done in v_map()] * * <obj> can both be an object reference or a filename. If <ob> is * omitted, or neither an object nor a string, then this_object() is used. * * As a bonus, all references to destructed objects in <arr> are replaced * by proper 0es. */ { struct_t *st; struct_t *res; svalue_t *arg; svalue_t *v, *w, *x; mp_int cnt; inter_sp = sp; arg = sp - num_arg + 1; st = arg->u.strct; cnt = (mp_int)struct_size(st); if (arg[1].type == T_MAPPING) { /* --- Map through mapping --- */ mapping_t *m; p_int column = 0; /* mapping column to use */ m = arg[1].u.map; if (num_arg > 2) column = arg[2].u.number; res = struct_new(st->type); if (!res) errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt); push_struct(inter_sp, res); /* In case of errors */ for (w = st->member, x = res->member; --cnt >= 0; w++, x++) { if (destructed_object_ref(w)) assign_svalue(w, &const0); v = get_map_value(m, w); if (v == &const0) assign_svalue_no_free(x, w); else assign_svalue_no_free(x, v + column); } if (num_arg > 2) free_svalue(arg+2); free_svalue(arg+1); /* the mapping */ sp = arg; } else { /* --- Map through function call --- */ callback_t cb; int error_index; error_index = setup_efun_callback(&cb, arg+1, num_arg-1); if (error_index >= 0) { vefun_bad_arg(error_index+2, arg); /* NOTREACHED */ return arg; } inter_sp = sp = arg+1; put_callback(sp, &cb); num_arg = 2; res = struct_new(st->type); if (!res) errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt); push_struct(inter_sp, res); /* In case of errors */ /* Loop through arr and res, mapping the values from arr */ for (w = st->member, x = res->member; --cnt >= 0; w++, x++) { if (current_object->flags & O_DESTRUCTED) continue; if (destructed_object_ref(w)) assign_svalue(w, &const0); if (!callback_object(&cb)) errorf("object used by map_array destructed"); push_svalue(w); v = apply_callback(&cb, 1); if (v) { transfer_svalue_no_free(x, v); v->type = T_INVALID; } } free_callback(&cb); } /* The arguments have been removed already, now just replace * the struct on the stack with the result. */ free_struct(st); arg->u.strct = res; /* Keep svalue type T_STRUCT */ return arg; } /* x_map_struct () */