/*parse config line*/
static int func_sys_parse_param(char *cfg_line)
{
	struct mod_conf_param *data = NULL;
	char* token = NULL;
	int flag = 0; 
	int temp;
	
	if ((token = strtok(cfg_line, w_space)) != NULL)
	{
		if(strcmp(token, "mod_no_cache_if_http_code"))
			goto err;	
	}
	else
	{
		debug(190, 3)("(mod_no_cache_if_http_code) ->  parse line error\n");
		goto err;	
	}	

	if(NULL == mod_config_pool)
	{
		mod_config_pool = memPoolCreate("mod_no_cache_if_http_code config_struct", sizeof(struct mod_conf_param));
	}
	data = memPoolAlloc(mod_config_pool);
	data->count = 0;
	while (NULL != (token = strtok(NULL, w_space)))
	{
		if(0 != strcmp(token, "allow") || 0 != strcmp(token, "deny"))	
		{
			if(49 == data->count)
			{
				debug(190, 3)("mod_no_cache_if_http_code : there are 49 values of squid`s http_code totally.\n");
				flag = 1;
				break;
			}
			if((temp = atoi(token)) >= 0)
			{
				data->http_code[data->count++] = temp; 
			}
			else
			{
				flag = 1;
				debug(190, 3)("mod_no_cache_if_http_code : there is something wrong during parsing the http code in config line\n");	
				break;
			}
		}
		else
		{
			flag = 0;
			break;
		}
	}

	if(1 == flag)
		goto err;
	cc_register_mod_param(mod, data, free_callback);
	return 0;		
err:
	free_callback(data);
	return -1;
}
Beispiel #2
0
// mod_check_response send=1 check=1 allow acl_name
// send, control send or not send X-CC-UP-CHECK header to client
// check, decide whether check X-CC-UP-CHECK value from origin
static int func_sys_parse_param(char *cfg_line)
{
	struct mod_conf_param *data = NULL;
	data = mod_config_pool_alloc();
	memset(data, 0, sizeof(struct mod_conf_param));

	char *token = NULL;
	if (NULL == (token = strtok(cfg_line, w_space)))
		goto error;
	if (strcmp(token, "mod_check_response"))
		goto error;

	while (NULL != (token = strtok(NULL, w_space))) {
		if (!strcasecmp(token, "allow") || !strcasecmp(token, "deny"))
			break;
		else if (!strcasecmp(token, "send=1")) 
			data->send = 1;
		else if (!strcasecmp(token, "check=1")) 
			data->check = 1;
	}

	debug(107,1)("mod_check_response: parse successfully, send=%d\tcheck=%d\n", data->send, data->check);
	cc_register_mod_param(mod, data, free_callback);
	return 0;

error:
	debug(107, 1)("mod_check_response: [%s] parse error\n", cfg_line);
	free_callback(data);
	return -1;		
}
Beispiel #3
0
static int func_sys_parse_param(char *cfg_line)
{
	debug(207,3)("mod_m3u8_prefetch config=[%s]\n", cfg_line);
	char* token = NULL;
	if ((token = strtok(cfg_line, w_space)) != NULL)
	{
		if(strcmp(token, "mod_m3u8_prefetch"))
			return -1;
	}
	else
	{
		debug(207, 3)("(mod_m3u8_prefetch) ->  parse line error\n");
		return -1;
	}

    debug(207, 3)("(mod_m3u8_prefetch) -> token1 = %s\n",token);
	if (NULL == (token = strtok(NULL, w_space)))
	{
		debug(207, 3)("(mod_m3u8_prefetch) ->  use default host!\n");
	}
    
	mod_config *cfg = mod_config_pool_alloc();
    if (strcasecmp(token, "beforeAdding") == 0) {//found this config param
        cfg->Before_flag = true;
        if (NULL == (token = strtok(NULL, w_space))) {
            debug(207, 3)("(mod_m3u8_prefetch) -> config error miss beforeAdding url\n");
            free_callback(cfg);
            return -1;
        }
        if (strncmp(token,"http://",strlen("http://")) != 0) {
            debug(207, 0)("mod_m3u8_prefetch config beforeAdding url not begin with http:// check config token=%s\n",token);
            free_callback(cfg);
            return -1;
        }
        debug(207, 3)("(mod_m3u8_prefetch) -> token2 = %s\n",token);
        strncpy(cfg->beforeAdding,token,strlen(token));
    } else {
        cfg->Before_flag = false;
    }

	debug(207, 2) ("(mod_m3u8_prefetch) ->  before_flag=%s beforeAdding=%s\n",cfg->Before_flag==true?"true":"false",cfg->beforeAdding);

	cc_register_mod_param(mod, cfg, free_callback);
	return 0;
}
Beispiel #4
0
/*-------------------------------------------------------------------------*/
static void
handle_tls_cb_error (error_handler_t * arg)

{
    tls_cb_handler_t * data = (tls_cb_handler_t *)arg;
    free_callback(data->cb);
    xfree(data->cb);
    xfree(arg);
} /* handle_tls_cb_error() */
void
list_free(list *head, void (*free_callback) (void *))
{
    list *l = head;
    list *next;
    while (l) {
        next = l->next;
        if (free_callback)
            free_callback(l->data);
        free(l);
        l = next;
    }
}
Beispiel #6
0
void emb_container_free(void *data_pp)
{
	emb_container_t *embc;
	void (*free_callback)(void *) = NULL;

	if (data_pp != NULL) {
		embc = container_of(data_pp, emb_container_t, data);

		free_callback = emb_type_get_callback(embc->type, "free");
		if (free_callback) {
			free_callback(embc->data);
		}
		embc->data = NULL;
		free(embc);
	}
}
Beispiel #7
0
void pscnv_mm_takedown(struct pscnv_mm *mm, void (*free_callback)(struct pscnv_mm_node *)) {
	struct pscnv_mm_node *cur;
	pscnv_mm_validate(mm, "before mm_takedown");
restart:
	cur = PSCNV_RB_MIN(pscnv_mm_head, &mm->head);
	cur = PSCNV_RB_NEXT(pscnv_mm_head, entry, cur);
	while (cur->type == PSCNV_MM_TYPE_FREE)
		cur = PSCNV_RB_NEXT(pscnv_mm_head, entry, cur);
	if (!cur->sentinel) {
		while (cur->prev)
			cur = cur->prev;
		if (pscnv_mm_debug >= 1)
			NV_INFO (mm->dev, "MM: [%s] takedown free %llx..%llx type %d\n", mm->name, cur->start, cur->start + cur->size, cur->type);
		free_callback(cur);
		goto restart;
	}
	while ((cur = PSCNV_RB_ROOT(&mm->head))) {
		PSCNV_RB_REMOVE(pscnv_mm_head, &mm->head, cur);
		kfree(cur);
	}
	kfree(mm);
}
Beispiel #8
0
callback*
create_callback(JNIEnv* env, jobject obj, jobject method,
                jobjectArray arg_classes, jclass return_class,
                callconv_t calling_convention, 
                jint options,
                jstring encoding) {
  jboolean direct = options & CB_OPTION_DIRECT;
  jboolean in_dll = options & CB_OPTION_IN_DLL;
  callback* cb;
  ffi_abi abi = (calling_convention == CALLCONV_C
		 ? FFI_DEFAULT_ABI : (ffi_abi)calling_convention);
  ffi_abi java_abi = FFI_DEFAULT_ABI;
  ffi_type* return_type;
  ffi_status status;
  jsize argc;
  JavaVM* vm;
  int rtype;
  char msg[MSG_SIZE];
  int i;
  int cvt = 0;
  const char* throw_type = NULL;
  const char* throw_msg = NULL;

  if ((*env)->GetJavaVM(env, &vm) != JNI_OK) {
    throwByName(env, EUnsatisfiedLink, "Couldn't obtain Java VM reference when creating native callback");
    return NULL;
  }
  argc = (*env)->GetArrayLength(env, arg_classes);

  cb = (callback *)malloc(sizeof(callback));
  cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure);
  cb->saved_x_closure = cb->x_closure;
  cb->object = (*env)->NewWeakGlobalRef(env, obj);
  cb->methodID = (*env)->FromReflectedMethod(env, method);

  cb->vm = vm;
  cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc);
  cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3));
  cb->arg_jtypes = (char*)malloc(sizeof(char) * argc);
  cb->conversion_flags = (int *)malloc(sizeof(int) * argc);
  cb->rflag = CVT_DEFAULT;
  cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc);
 
  cb->direct = direct;
  cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer;
  cb->encoding = newCStringUTF8(env, encoding);

  for (i=0;i < argc;i++) {
    int jtype;
    jclass cls = (*env)->GetObjectArrayElement(env, arg_classes, i);
    if ((cb->conversion_flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT) {
      cb->arg_classes[i] = (*env)->NewWeakGlobalRef(env, cls);
      cvt = 1;
    }
    else {
      cb->arg_classes[i] = NULL;
    }

    jtype = get_java_type(env, cls);
    if (jtype == -1) {
      snprintf(msg, sizeof(msg), "Unsupported callback argument at index %d", i);
      throw_type = EIllegalArgument;
      throw_msg = msg;
      goto failure_cleanup;
    }
    cb->arg_jtypes[i] = (char)jtype;
    cb->java_arg_types[i+3] = cb->arg_types[i] = get_ffi_type(env, cls, cb->arg_jtypes[i]);
    if (!cb->java_arg_types[i+3]) {
      goto failure_cleanup;
    }
    if (cb->conversion_flags[i] == CVT_NATIVE_MAPPED
        || cb->conversion_flags[i] == CVT_POINTER_TYPE
        || cb->conversion_flags[i] == CVT_INTEGER_TYPE) {
      jclass ncls;
      ncls = getNativeType(env, cls);
      jtype = get_java_type(env, ncls);
      if (jtype == -1) {
        snprintf(msg, sizeof(msg), "Unsupported NativeMapped callback argument native type at argument %d", i);
        throw_type = EIllegalArgument;
        throw_msg = msg;
        goto failure_cleanup;
      }
      cb->arg_jtypes[i] = (char)jtype;
      cb->java_arg_types[i+3] = &ffi_type_pointer;
      cb->arg_types[i] = get_ffi_type(env, ncls, cb->arg_jtypes[i]);
      if (!cb->arg_types[i]) {
        goto failure_cleanup;
      }
    }

    // Java callback method is called using varargs, so promote floats to 
    // double where appropriate for the platform
    if (cb->arg_types[i]->type == FFI_TYPE_FLOAT) {
      cb->java_arg_types[i+3] = &ffi_type_double;
      cb->conversion_flags[i] = CVT_FLOAT;
      cvt = 1;
    }
    else if (cb->java_arg_types[i+3]->type == FFI_TYPE_STRUCT) {
      // All callback structure arguments are passed as a jobject
      cb->java_arg_types[i+3] = &ffi_type_pointer;
    }
  }
  if (!direct || !cvt) {
    free(cb->conversion_flags);
    cb->conversion_flags = NULL;
    free(cb->arg_classes);
    cb->arg_classes = NULL;
  }
  if (direct) {
    cb->rflag = get_conversion_flag(env, return_class);
    if (cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_INTEGER_TYPE
        || cb->rflag == CVT_POINTER_TYPE) {
      return_class = getNativeType(env, return_class);
    }
  }

#if defined(_WIN32)
  if (calling_convention == CALLCONV_STDCALL) {
#if defined(_WIN64) || defined(_WIN32_WCE)
    // Ignore requests for stdcall on win64/wince
    abi = FFI_DEFAULT_ABI;
#else
    abi = FFI_STDCALL;
    // All JNI entry points on win32 use stdcall
    java_abi = FFI_STDCALL;
#endif
  }
#endif // _WIN32

  if (!(abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) {
    snprintf(msg, sizeof(msg), "Invalid calling convention %d", abi);
    throw_type = EIllegalArgument;
    throw_msg = msg;
    goto failure_cleanup;
  }

  rtype = get_java_type(env, return_class);
  if (rtype == -1) {
    throw_type = EIllegalArgument;
    throw_msg = "Unsupported callback return type";
    goto failure_cleanup;
  }
  return_type = get_ffi_return_type(env, return_class, (char)rtype);
  if (!return_type) {
    throw_type = EIllegalArgument;
    throw_msg = "Error in callback return type";
    goto failure_cleanup;
  }
  status = ffi_prep_cif(&cb->cif, abi, argc, return_type, cb->arg_types);
  if (!ffi_error(env, "callback setup", status)) {
    ffi_type* java_return_type = return_type;

    if (cb->rflag == CVT_STRUCTURE_BYVAL
        || cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_POINTER_TYPE
        || cb->rflag == CVT_INTEGER_TYPE) {
      // Java method returns a jobject, not a struct
      java_return_type = &ffi_type_pointer;
      rtype = '*';
    }
    switch(rtype) {
#define OFFSETOF(ENV,METHOD) ((size_t)((char *)&(*(ENV))->METHOD - (char *)(*(ENV))))
    case 'V': cb->fptr_offset = OFFSETOF(env, CallVoidMethod); break;
    case 'Z': cb->fptr_offset = OFFSETOF(env, CallBooleanMethod); break;
    case 'B': cb->fptr_offset = OFFSETOF(env, CallByteMethod); break;
    case 'S': cb->fptr_offset = OFFSETOF(env, CallShortMethod); break;
    case 'C': cb->fptr_offset = OFFSETOF(env, CallCharMethod); break;
    case 'I': cb->fptr_offset = OFFSETOF(env, CallIntMethod); break;
    case 'J': cb->fptr_offset = OFFSETOF(env, CallLongMethod); break;
    case 'F': cb->fptr_offset = OFFSETOF(env, CallFloatMethod); break;
    case 'D': cb->fptr_offset = OFFSETOF(env, CallDoubleMethod); break;
    default: cb->fptr_offset = OFFSETOF(env, CallObjectMethod); break;
    }
    status = ffi_prep_cif_var(&cb->java_cif, java_abi, 2, argc+3, java_return_type, cb->java_arg_types);
    if (!ffi_error(env, "callback setup (2)", status)) {
      ffi_prep_closure_loc(cb->closure, &cb->cif, dispatch_callback, cb,
                           cb->x_closure);
#ifdef DLL_FPTRS
      // Find an available function pointer and assign it
      if (in_dll) {
        for (i=0;i < DLL_FPTRS;i++) {
          if (fn[i] == NULL) {
            fn[i] = cb->x_closure;
            cb->x_closure = dll_fptrs[i];
            break;
          }
        }
        if (i == DLL_FPTRS) {
          throw_type = EOutOfMemory;
          throw_msg = "No more DLL callback slots available";
          goto failure_cleanup;
        }
      }
#endif
      return cb;
    }
  }

 failure_cleanup:
  free_callback(env, cb);
  if (throw_type) {
    throwByName(env, throw_type, throw_msg);
  }

  return NULL;
}
Beispiel #9
0
callback*
create_callback(JNIEnv* env, jobject obj, jobject method,
                jobjectArray param_types, jclass return_type,
                callconv_t calling_convention, jboolean direct) {
  callback* cb;
  ffi_abi abi = FFI_DEFAULT_ABI;
  ffi_abi java_abi = FFI_DEFAULT_ABI;
  ffi_type* ffi_rtype;
  ffi_status status;
  jsize argc;
  JavaVM* vm;
  int rtype;
  char msg[64];
  int i;
  int cvt = 0;
  const char* throw_type = NULL;
  const char* throw_msg = NULL;

  if ((*env)->GetJavaVM(env, &vm) != JNI_OK) {
    throwByName(env, EUnsatisfiedLink, "Can't get Java VM");
    return NULL;
  }
  argc = (*env)->GetArrayLength(env, param_types);

  cb = (callback *)malloc(sizeof(callback));
  cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure);
  cb->object = (*env)->NewWeakGlobalRef(env, obj);
  cb->methodID = (*env)->FromReflectedMethod(env, method);
  cb->vm = vm;
  cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc);
  cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3));
  cb->arg_jtypes = (char*)malloc(sizeof(char) * argc);
  cb->flags = (int *)malloc(sizeof(int) * argc);
  cb->rflag = CVT_DEFAULT;
  cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc);
 
  cb->direct = direct;
  cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer;

  for (i=0;i < argc;i++) {
    int jtype;
    jclass cls = (*env)->GetObjectArrayElement(env, param_types, i);
    if ((cb->flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT) {
      cb->arg_classes[i] = (*env)->NewWeakGlobalRef(env, cls);
      cvt = 1;
    }

    jtype = get_jtype(env, cls);
    if (jtype == -1) {
      snprintf(msg, sizeof(msg), "Unsupported argument at index %d", i);
      throw_type = EIllegalArgument;
      throw_msg = msg;
      goto failure_cleanup;
    }
    cb->arg_jtypes[i] = (char)jtype;
    cb->java_arg_types[i+3] = cb->arg_types[i] = get_ffi_type(env, cls, cb->arg_jtypes[i]);
    if (cb->flags[i] == CVT_NATIVE_MAPPED
        || cb->flags[i] == CVT_POINTER_TYPE
        || cb->flags[i] == CVT_INTEGER_TYPE) {
      jclass ncls;
      ncls = getNativeType(env, cls);
      jtype = get_jtype(env, ncls);
      if (jtype == -1) {
        snprintf(msg, sizeof(msg), "Unsupported NativeMapped argument native type at argument %d", i);
        throw_type = EIllegalArgument;
        throw_msg = msg;
        goto failure_cleanup;
      }
      cb->arg_jtypes[i] = (char)jtype;
      cb->java_arg_types[i+3] = &ffi_type_pointer;
      cb->arg_types[i] = get_ffi_type(env, ncls, cb->arg_jtypes[i]);
    }

    if (cb->arg_types[i]->type == FFI_TYPE_FLOAT) {
      // Java method is varargs, so promote floats to double
      cb->java_arg_types[i+3] = &ffi_type_double;
      cb->flags[i] = CVT_FLOAT;
      cvt = 1;
    }
    else if (cb->java_arg_types[i+3]->type == FFI_TYPE_STRUCT) {
      // All callback structure arguments are passed as a jobject
      cb->java_arg_types[i+3] = &ffi_type_pointer;
    }
  }
  if (!direct || !cvt) {
    free(cb->flags);
    cb->flags = NULL;
    free(cb->arg_classes);
    cb->arg_classes = NULL;
  }
  if (direct) {
    cb->rflag = get_conversion_flag(env, return_type);
    if (cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_INTEGER_TYPE
        || cb->rflag == CVT_POINTER_TYPE) {
      return_type = getNativeType(env, return_type);
    }
  }

#if defined(_WIN32) && !defined(_WIN64)
  if (calling_convention == CALLCONV_STDCALL) {
    abi = FFI_STDCALL;
  }
  java_abi = FFI_STDCALL;
#endif // _WIN32

  rtype = get_jtype(env, return_type);
  if (rtype == -1) {
    throw_type = EIllegalArgument;
    throw_msg = "Unsupported return type";
    goto failure_cleanup;
  }
  ffi_rtype = get_ffi_rtype(env, return_type, (char)rtype);
  if (!ffi_rtype) {
    throw_type = EIllegalArgument;
    throw_msg = "Error in return type";
    goto failure_cleanup;
  }
  status = ffi_prep_cif(&cb->cif, abi, argc, ffi_rtype, cb->arg_types);
  if (!ffi_error(env, "callback setup", status)) {
    ffi_type* java_ffi_rtype = ffi_rtype;

    if (cb->rflag == CVT_STRUCTURE_BYVAL
        || cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_POINTER_TYPE
        || cb->rflag == CVT_INTEGER_TYPE) {
      // Java method returns a jobject, not a struct
      java_ffi_rtype = &ffi_type_pointer;
      rtype = '*';
    }
    switch(rtype) {
    case 'V': cb->fptr = (*env)->CallVoidMethod; break;
    case 'Z': cb->fptr = (*env)->CallBooleanMethod; break;
    case 'B': cb->fptr = (*env)->CallByteMethod; break;
    case 'S': cb->fptr = (*env)->CallShortMethod; break;
    case 'C': cb->fptr = (*env)->CallCharMethod; break;
    case 'I': cb->fptr = (*env)->CallIntMethod; break;
    case 'J': cb->fptr = (*env)->CallLongMethod; break;
    case 'F': cb->fptr = (*env)->CallFloatMethod; break;
    case 'D': cb->fptr = (*env)->CallDoubleMethod; break;
    default: cb->fptr = (*env)->CallObjectMethod; break;
    }
    status = ffi_prep_cif(&cb->java_cif, java_abi, argc+3, java_ffi_rtype, cb->java_arg_types);
    if (!ffi_error(env, "callback setup (2)", status)) {
      ffi_prep_closure_loc(cb->closure, &cb->cif, callback_dispatch, cb,
                           cb->x_closure);
      return cb;
    }
  }

 failure_cleanup:
  free_callback(env, cb);
  if (throw_type) {
    throwByName(env, throw_type, msg);
  }

  return NULL;
}
Beispiel #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 () */
Beispiel #11
0
void ewg_ffcall_free_callback (void* a_function)
{
  free_callback (a_function);
}