Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
 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;
   }
 }
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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");
}
Ejemplo n.º 5
0
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";
}
Ejemplo n.º 6
0
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();
}
Ejemplo n.º 7
0
/*
 * 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);
    }
}
Ejemplo n.º 8
0
/*-------------------------------------------------------------------------*/
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() */
Ejemplo n.º 9
0
/*-------------------------------------------------------------------------*/
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);
            }
        }
Ejemplo n.º 10
0
/*-------------------------------------------------------------------------*/
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 () */