Esempio n. 1
0
void
rbgobj_init_flags_class(VALUE klass)
{
    GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
    GString* source = g_string_new(NULL);
    guint i;

    for (i = 0; i < gclass->n_values; i++) {
        GFlagsValue* entry = &(gclass->values[i]);
        gchar* nick;
        gchar* p;
        gchar* replace_nick;

        replace_nick = rg_obj_constant_lookup(entry->value_nick);
        if (replace_nick){
            nick = g_strdup(replace_nick);
        } else {
            nick = g_strdup(entry->value_nick);
        }

        for (p = nick; *p; p++)
            if (*p == '-' || *p == ' ')
                *p = '_';
            else
                *p = tolower(*p);

        g_string_append_printf(
            source,
            "def %s%s?; self >= self.class.new(%d); end\n",
            g_ascii_isdigit(nick[0]) ? "_" : "",
            nick, entry->value);

        for (p = nick; *p; p++)
            *p = g_ascii_toupper(*p);

#if 0
        {
            ID id = rb_intern(nick);
            if (rb_is_const_id(id)) {
                rb_define_const(klass, nick, make_flags(entry->value, klass));
            }
        }
#else
        {
            rbgobj_define_const(klass, nick, make_flags(entry->value, klass));
        }
#endif

        g_free(nick);
    }

    rb_funcall(klass, id_module_eval, 3,
               rb_str_new2(source->str),
               rb_str_new2(__FILE__),
               INT2NUM(__LINE__));
    g_string_free(source, TRUE);

    g_type_class_unref(gclass);
}
Esempio n. 2
0
static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
		     unsigned int flags)
{
	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
	int req;
	u32 lkf;
	char strname[GDLM_STRNAME_BYTES] = "";

	req = make_mode(req_state);
	lkf = make_flags(gl, flags, req);
	gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
	gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
	if (gl->gl_lksb.sb_lkid) {
		gfs2_update_request_times(gl);
	} else {
		memset(strname, ' ', GDLM_STRNAME_BYTES - 1);
		strname[GDLM_STRNAME_BYTES - 1] = '\0';
		gfs2_reverse_hex(strname + 7, gl->gl_name.ln_type);
		gfs2_reverse_hex(strname + 23, gl->gl_name.ln_number);
		gl->gl_dstamp = ktime_get_real();
	}
	/*
	 * Submit the actual lock request.
	 */

	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, strname,
			GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}
Esempio n. 3
0
    PileupItf * ReferenceItf :: getFilteredPileupSlice ( int64_t start, uint64_t length, uint32_t categories, uint32_t filters, int32_t mappingQuality ) const
        throw ( ErrorMsg )
    {
        // the object is really from C
        const NGS_Reference_v1 * self = Test ();

        // test for conflicting filters
        const uint32_t conflictingMapQuality = Alignment :: minMapQuality | Alignment :: maxMapQuality;
        if ( ( filters & conflictingMapQuality ) == conflictingMapQuality )
            throw ErrorMsg ( "mapping quality can only be used as a minimum or maximum value, not both" );

        // cast vtable to our level
        const NGS_Reference_v1_vt * vt = Access ( self -> vt );

        // test for v1.1
        if ( vt -> dad . minor_version < 1 )
            throw ErrorMsg ( "the Reference interface provided by this NGS engine is too old to support this message" );

        // test for bad categories
        // this should not be possible in C++, but it is possible from other bindings
        if ( categories == 0 )
            categories = Alignment :: primaryAlignment;

        // call through C vtable
        ErrBlock err;
        assert ( vt -> get_filtered_pileup_slice != 0 );
        uint32_t flags = make_flags ( categories, filters );
        NGS_Pileup_v1 * ret  = ( * vt -> get_filtered_pileup_slice ) ( self, & err, start, length, flags, mappingQuality );

        // check for errors
        err . Check ();

        return PileupItf :: Cast ( ret );
    }
Esempio n. 4
0
void setupSysEnd() {
    std::vector<Box*> builtin_module_names;
    for (int i = 0; PyImport_Inittab[i].name != NULL; i++)
        builtin_module_names.push_back(boxString(PyImport_Inittab[i].name));

    std::sort<decltype(builtin_module_names)::iterator, PyLt>(builtin_module_names.begin(), builtin_module_names.end(),
                                                              PyLt());

    sys_module->giveAttr("builtin_module_names",
                         BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0]));

    for (Box* b : builtin_module_names)
        Py_DECREF(b);

#ifndef NDEBUG
    for (const auto& p : *sys_modules_dict) {
        assert(PyString_Check(p.first));

        bool found = false;
        for (int i = 0; PyImport_Inittab[i].name != NULL; i++) {
            if (((BoxedString*)p.first)->s() == PyImport_Inittab[i].name) {
                found = true;
            }
        }
        if (!found)
            assert(0 && "found a module which is inside sys.modules but not listed inside PyImport_Inittab!");
    }
#endif

    /* version_info */
    if (VersionInfoType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&VersionInfoType, &version_info_desc);
    /* prevent user from creating new instances */
    VersionInfoType.tp_init = NULL;
    VersionInfoType.tp_new = NULL;

    SET_SYS_FROM_STRING("version_info", make_version_info());

    /* float_info */
    if (FloatInfoType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&FloatInfoType, &float_info_desc);
    /* flags */
    if (FlagsType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&FlagsType, &flags_desc);
    SET_SYS_FROM_STRING("flags", make_flags());
    /* prevent user from creating new instances */
    FlagsType.tp_init = NULL;
    FlagsType.tp_new = NULL;
    /* prevent user from creating new instances */
    FloatInfoType.tp_init = NULL;
    FloatInfoType.tp_new = NULL;

    SET_SYS_FROM_STRING("float_info", PyFloat_GetInfo());
}
Esempio n. 5
0
static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
		     unsigned int flags)
{
	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
	int req;
	u32 lkf;

	req = make_mode(req_state);
	lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

	/*
	 * Submit the actual lock request.
	 */

	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
			GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}
Esempio n. 6
0
static VALUE
rg_s_values(VALUE klass)
{
    GFlagsClass *gclass;
    VALUE result;
    guint i;

    gclass = g_type_class_ref(CLASS2GTYPE(klass));
    result = rb_ary_new();
    for (i = 0; i < gclass->n_values; i++) {
        GFlagsValue *p = &(gclass->values[i]);
        rb_ary_push(result, make_flags(p->value, klass));
    }
    g_type_class_unref(gclass);

    return result;
}
Esempio n. 7
0
static unsigned int gdlm_lock(struct gfs2_glock *gl,
                              unsigned int req_state, unsigned int flags)
{
    struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
    int error;
    int req;
    u32 lkf;

    gl->gl_req = req_state;
    req = make_mode(req_state);
    lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

    /*
     * Submit the actual lock request.
     */

    error = dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
                     GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
    if (error == -EAGAIN)
        return 0;
    if (error)
        return LM_OUT_ERROR;
    return LM_OUT_ASYNC;
}
/* XSB regular expression matcher entry point
   In:
       Arg1: regexp
       Arg2: string
       Arg3: offset
       Arg4: match_flags: Var means case-sensitive/extended;
       	       	          number: ignorecase/extended
			  List: [{extended|ignorecase},...]
   Out:
       Arg5: list of the form [match(bo0,eo0), match(bo1,eo1),...]
       	     where bo*,eo* specify the beginning and ending offsets of the
	     matched substrings.
	     All matched substrings are returned. Parenthesized expressions are
	     ignored.
*/
int do_bulkmatch__(void)
{
#ifdef MULTI_THREAD
  if( NULL == th)
	th = xsb_get_main_thread();
#endif

  prolog_term listHead, listTail;
  /* Prolog args are first assigned to these, so we could examine the types
     of these objects to determine if we got strings or atoms. */
  prolog_term regexp_term, input_term, offset_term;
  prolog_term output_term = p2p_new(CTXT);
  char *regexp_ptr=NULL;      /* regular expression ptr	       	      */
  char *input_string=NULL;    /* string where matches are to be found */
  int match_flags=FALSE;
  int return_code, paren_number, offset;
  regmatch_t *match_array;
  int last_pos=0, input_len;
  
  if (first_call)
    initialize_regexp_tbl();

  regexp_term = reg_term(CTXTc 1);  /* Arg1: regexp */
  if (is_string(regexp_term)) /* check it */
    regexp_ptr = string_val(regexp_term);
  else if (is_list(regexp_term))
    regexp_ptr = p_charlist_to_c_string(CTXTc regexp_term, &regexp_buffer,
					"RE_BULKMATCH", "regular expression");
  else
    xsb_abort("[RE_BULKMATCH] Arg 1 (the regular expression) must be an atom or a character list");

  input_term = reg_term(CTXTc 2);  /* Arg2: string to find matches in */
  if (is_string(input_term)) /* check it */
    input_string = string_val(input_term);
  else if (is_list(input_term)) {
    input_string = p_charlist_to_c_string(CTXTc input_term, &input_buffer,
					  "RE_BULKMATCH", "input string");
  } else
    xsb_abort("[RE_BULKMATCH] Arg 2 (the input string) must be an atom or a character list");

  input_len = strlen(input_string);
  
  offset_term = reg_term(CTXTc 3); /* arg3: offset within the string */
  if (! is_int(offset_term))
    xsb_abort("[RE_BULKMATCH] Arg 3 (the offset) must be an integer");
  offset = int_val(offset_term);
  if (offset < 0 || offset > input_len)
    xsb_abort("[RE_BULKMATCH] Arg 3 (=%d) must be between 0 and %d", input_len);

   /* arg 4 specifies flags: _, number, list [extended,ignorecase] */
  match_flags = make_flags(reg_term(CTXTc 4), "RE_BULKMATCH");

  last_pos = offset;
  /* returned result */
  listTail = output_term;
  while (last_pos < input_len) {
    return_code = xsb_re_match(regexp_ptr, input_string+last_pos, match_flags,
			       &match_array, &paren_number, "RE_BULKMATCH");
    /* exit on no match */
    if (! return_code) break;

    c2p_list(CTXTc listTail); /* make it into a list */
    listHead = p2p_car(listTail); /* get head of the list */

    /* bind i-th match to listHead as match(beg,end) */
    c2p_functor(CTXTc "match", 2, listHead);
    c2p_int(CTXTc match_array[0].rm_so+last_pos, p2p_arg(listHead,1));
    c2p_int(CTXTc match_array[0].rm_eo+last_pos, p2p_arg(listHead,2));

    listTail = p2p_cdr(listTail);
    if (match_array[0].rm_eo > 0)
      last_pos = match_array[0].rm_eo+last_pos;
    else
      last_pos++;
  }

  c2p_nil(CTXTc listTail); /* bind tail to nil */
  return p2p_unify(CTXTc output_term, reg_term(CTXTc 5));
}
 bool init_method_flags_atomic(TosState return_type, int option_bits, int method_params) {
     assert((method_params & parameter_size_mask) == method_params, "method_params in range");
     return init_flags_atomic(make_flags(return_type, option_bits, method_params));
 }
Esempio n. 10
0
 void set_method_flags(TosState return_type, int option_bits, int method_params) {
     assert((method_params & parameter_size_mask) == method_params, "method_params in range");
     set_flags(make_flags(return_type, option_bits, method_params));
 }
Esempio n. 11
0
 void set_field_flags(TosState field_type, int option_bits, int field_index) {
     assert((field_index & field_index_mask) == field_index, "field_index in range");
     set_flags(make_flags(field_type, option_bits | (1 << is_field_entry_shift), field_index));
 }
Esempio n. 12
0
static void
box_closed_p2( sync_vars_t *svars, int t )
{
	sync_rec_t *srec;
	int minwuid;
	char fbuf[16]; /* enlarge when support for keywords is added */

	svars->state[t] |= ST_CLOSED;
	if (!(svars->state[1-t] & ST_CLOSED))
		return;

	if ((svars->state[M] | svars->state[S]) & ST_DID_EXPUNGE) {
		/* This cleanup is not strictly necessary, as the next full sync
		   would throw out the dead entries anyway. But ... */

		minwuid = INT_MAX;
		if (svars->smaxxuid) {
			debug( "preparing entry purge - max expired slave uid is %d\n", svars->smaxxuid );
			for (srec = svars->srecs; srec; srec = srec->next) {
				if (srec->status & S_DEAD)
					continue;
				if (!((srec->uid[S] <= 0 || ((srec->status & S_DEL(S)) && (svars->state[S] & ST_DID_EXPUNGE))) &&
				      (srec->uid[M] <= 0 || ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE)) || (srec->status & S_EXPIRED))) &&
				    svars->smaxxuid < srec->uid[S] && minwuid > srec->uid[M])
					minwuid = srec->uid[M];
			}
			debug( "  min non-orphaned master uid is %d\n", minwuid );
		}

		for (srec = svars->srecs; srec; srec = srec->next) {
			if (srec->status & S_DEAD)
				continue;
			if (srec->uid[S] <= 0 || ((srec->status & S_DEL(S)) && (svars->state[S] & ST_DID_EXPUNGE))) {
				if (srec->uid[M] <= 0 || ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE)) ||
				    ((srec->status & S_EXPIRED) && svars->maxuid[M] >= srec->uid[M] && minwuid > srec->uid[M])) {
					debug( "  -> killing (%d,%d)\n", srec->uid[M], srec->uid[S] );
					srec->status = S_DEAD;
					Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] );
				} else if (srec->uid[S] > 0) {
					debug( "  -> orphaning (%d,[%d])\n", srec->uid[M], srec->uid[S] );
					Fprintf( svars->jfp, "> %d %d 0\n", srec->uid[M], srec->uid[S] );
					srec->uid[S] = 0;
				}
			} else if (srec->uid[M] > 0 && ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE))) {
				debug( "  -> orphaning ([%d],%d)\n", srec->uid[M], srec->uid[S] );
				Fprintf( svars->jfp, "< %d %d 0\n", srec->uid[M], srec->uid[S] );
				srec->uid[M] = 0;
			}
		}
	}

	Fprintf( svars->nfp, "%d:%d %d:%d:%d\n",
	         svars->uidval[M], svars->maxuid[M],
	         svars->uidval[S], svars->smaxxuid, svars->maxuid[S] );
	for (srec = svars->srecs; srec; srec = srec->next) {
		if (srec->status & S_DEAD)
			continue;
		make_flags( srec->flags, fbuf );
		Fprintf( svars->nfp, "%d %d %s%s\n", srec->uid[M], srec->uid[S],
		         srec->status & S_EXPIRED ? "X" : "", fbuf );
	}

	Fclose( svars->nfp, 1 );
	Fclose( svars->jfp, 0 );
	if (!(DFlags & KEEPJOURNAL)) {
		/* order is important! */
		rename( svars->nname, svars->dname );
		unlink( svars->jname );
	}

	sync_bail( svars );
}
Esempio n. 13
0
static void
box_loaded( int sts, void *aux )
{
	DECL_SVARS;
	sync_rec_t *srec;
	sync_rec_map_t *srecmap;
	message_t *tmsg;
	copy_vars_t *cv;
	flag_vars_t *fv;
	int uid, minwuid, *mexcs, nmexcs, rmexcs, no[2], del[2], todel, t1, t2;
	int sflags, nflags, aflags, dflags, nex;
	unsigned hashsz, idx;
	char fbuf[16]; /* enlarge when support for keywords is added */

	if (check_ret( sts, aux ))
		return;
	INIT_SVARS(aux);
	svars->state[t] |= ST_LOADED;
	info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent );

	if (svars->state[t] & S_FIND) {
		svars->state[t] &= ~S_FIND;
		debug( "matching previously copied messages on %s\n", str_ms[t] );
		match_tuids( svars, t );
	}

	debug( "matching messages on %s against sync records\n", str_ms[t] );
	hashsz = bucketsForSize( svars->nsrecs * 3 );
	srecmap = nfcalloc( hashsz * sizeof(*srecmap) );
	for (srec = svars->srecs; srec; srec = srec->next) {
		if (srec->status & S_DEAD)
			continue;
		uid = srec->uid[t];
		idx = (unsigned)((unsigned)uid * 1103515245U) % hashsz;
		while (srecmap[idx].uid)
			if (++idx == hashsz)
				idx = 0;
		srecmap[idx].uid = uid;
		srecmap[idx].srec = srec;
	}
	for (tmsg = svars->ctx[t]->msgs; tmsg; tmsg = tmsg->next) {
		if (tmsg->srec) /* found by TUID */
			continue;
		uid = tmsg->uid;
		if (DFlags & DEBUG) {
			make_flags( tmsg->flags, fbuf );
			printf( svars->ctx[t]->opts & OPEN_SIZE ? "  message %5d, %-4s, %6lu: " : "  message %5d, %-4s: ", uid, fbuf, tmsg->size );
		}
		idx = (unsigned)((unsigned)uid * 1103515245U) % hashsz;
		while (srecmap[idx].uid) {
			if (srecmap[idx].uid == uid) {
				srec = srecmap[idx].srec;
				goto found;
			}
			if (++idx == hashsz)
				idx = 0;
		}
		tmsg->srec = 0;
		debug( "new\n" );
		continue;
	  found:
		tmsg->srec = srec;
		srec->msg[t] = tmsg;
		debug( "pairs %5d\n", srec->uid[1-t] );
	}
	free( srecmap );

	if ((t == S) && svars->smaxxuid) {
		debug( "preparing master selection - max expired slave uid is %d\n", svars->smaxxuid );
		mexcs = 0;
		nmexcs = rmexcs = 0;
		minwuid = INT_MAX;
		for (srec = svars->srecs; srec; srec = srec->next) {
			if (srec->status & S_DEAD)
				continue;
			if (srec->status & S_EXPIRED) {
				if (!srec->uid[S] || ((svars->ctx[S]->opts & OPEN_OLD) && !srec->msg[S])) {
					srec->status |= S_EXP_S;
					continue;
				}
			} else {
				if (svars->smaxxuid >= srec->uid[S])
					continue;
			}
			if (minwuid > srec->uid[M])
				minwuid = srec->uid[M];
		}
		debug( "  min non-orphaned master uid is %d\n", minwuid );
		for (srec = svars->srecs; srec; srec = srec->next) {
			if (srec->status & S_DEAD)
				continue;
			if (srec->status & S_EXP_S) {
				if (minwuid > srec->uid[M] && svars->maxuid[M] >= srec->uid[M]) {
					debug( "  -> killing (%d,%d)\n", srec->uid[M], srec->uid[S] );
					srec->status = S_DEAD;
					Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] );
				} else if (srec->uid[S]) {
					debug( "  -> orphaning (%d,[%d])\n", srec->uid[M], srec->uid[S] );
					Fprintf( svars->jfp, "> %d %d 0\n", srec->uid[M], srec->uid[S] );
					srec->uid[S] = 0;
				}
			} else if (minwuid > srec->uid[M]) {
				if (srec->uid[S] < 0) {
					if (svars->maxuid[M] >= srec->uid[M]) {
						debug( "  -> killing (%d,%d)\n", srec->uid[M], srec->uid[S] );
						srec->status = S_DEAD;
						Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] );
					}
				} else if (srec->uid[M] > 0 && srec->uid[S] && (svars->ctx[M]->opts & OPEN_OLD) &&
				           (!(svars->ctx[M]->opts & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) {
					if (nmexcs == rmexcs) {
						rmexcs = rmexcs * 2 + 100;
						mexcs = nfrealloc( mexcs, rmexcs * sizeof(int) );
					}
					mexcs[nmexcs++] = srec->uid[M];
				}
			}
		}
		debugn( "  exception list is:" );
		for (t = 0; t < nmexcs; t++)
			debugn( " %d", mexcs[t] );
		debug( "\n" );
		load_box( svars, M, minwuid, mexcs, nmexcs );
		return;
	}

	if (!(svars->state[1-t] & ST_LOADED))
		return;

	if (svars->uidval[M] < 0 || svars->uidval[S] < 0) {
		svars->uidval[M] = svars->ctx[M]->uidvalidity;
		svars->uidval[S] = svars->ctx[S]->uidvalidity;
		Fprintf( svars->jfp, "| %d %d\n", svars->uidval[M], svars->uidval[S] );
	}

	info( "Synchronizing...\n" );

	debug( "synchronizing new entries\n" );
	svars->osrecadd = svars->srecadd;
	for (t = 0; t < 2; t++) {
		Fprintf( svars->jfp, "%c %d\n", "{}"[t], svars->ctx[t]->uidnext );
		for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next)
			if (tmsg->srec ? tmsg->srec->uid[t] < 0 && (tmsg->srec->uid[t] == -1 ? (svars->chan->ops[t] & OP_RENEW) : (svars->chan->ops[t] & OP_NEW)) : (svars->chan->ops[t] & OP_NEW)) {
				debug( "new message %d on %s\n", tmsg->uid, str_ms[1-t] );
				if ((svars->chan->ops[t] & OP_EXPUNGE) && (tmsg->flags & F_DELETED))
					debug( "  -> not %sing - would be expunged anyway\n", str_hl[t] );
				else {
					if (tmsg->srec) {
						srec = tmsg->srec;
						srec->status |= S_DONE;
						debug( "  -> pair(%d,%d) exists\n", srec->uid[M], srec->uid[S] );
					} else {
						srec = nfmalloc( sizeof(*srec) );
						srec->next = 0;
						*svars->srecadd = srec;
						svars->srecadd = &srec->next;
						svars->nsrecs++;
						srec->status = S_DONE;
						srec->flags = 0;
						srec->tuid[0] = 0;
						srec->uid[1-t] = tmsg->uid;
						srec->uid[t] = -2;
						Fprintf( svars->jfp, "+ %d %d\n", srec->uid[M], srec->uid[S] );
						debug( "  -> pair(%d,%d) created\n", srec->uid[M], srec->uid[S] );
					}
					if ((tmsg->flags & F_FLAGGED) || !svars->chan->stores[t]->max_size || tmsg->size <= svars->chan->stores[t]->max_size) {
						if (tmsg->flags) {
							srec->flags = tmsg->flags;
							Fprintf( svars->jfp, "* %d %d %u\n", srec->uid[M], srec->uid[S], srec->flags );
							debug( "  -> updated flags to %u\n", tmsg->flags );
						}
						for (t1 = 0; t1 < TUIDL; t1++) {
							t2 = arc4_getbyte() & 0x3f;
							srec->tuid[t1] = t2 < 26 ? t2 + 'A' : t2 < 52 ? t2 + 'a' - 26 : t2 < 62 ? t2 + '0' - 52 : t2 == 62 ? '+' : '/';
						}
						svars->new_total[t]++;
						stats( svars );
						cv = nfmalloc( sizeof(*cv) );
						cv->cb = msg_copied;
						cv->aux = AUX;
						cv->srec = srec;
						cv->msg = tmsg;
						Fprintf( svars->jfp, "# %d %d %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid );
						if (FSyncLevel >= FSYNC_THOROUGH)
							fdatasync( fileno( svars->jfp ) );
						debug( "  -> %sing message, TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid );
						if (copy_msg( cv ))
							return;
					} else {
						if (tmsg->srec) {
							debug( "  -> not %sing - still too big\n", str_hl[t] );
							continue;
						}
						debug( "  -> not %sing - too big\n", str_hl[t] );
						msg_copied_p2( svars, srec, t, tmsg, -1 );
					}
				}
			}
		svars->state[t] |= ST_SENT_NEW;
		msgs_copied( svars, t );
	}

	debug( "synchronizing old entries\n" );
	for (srec = svars->srecs; srec != *svars->osrecadd; srec = srec->next) {
		if (srec->status & (S_DEAD|S_DONE))
			continue;
		debug( "pair (%d,%d)\n", srec->uid[M], srec->uid[S] );
		no[M] = !srec->msg[M] && (svars->ctx[M]->opts & OPEN_OLD);
		no[S] = !srec->msg[S] && (svars->ctx[S]->opts & OPEN_OLD);
		if (no[M] && no[S]) {
			debug( "  vanished\n" );
			/* d.1) d.5) d.6) d.10) d.11) */
			srec->status = S_DEAD;
			Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] );
		} else {
			del[M] = no[M] && (srec->uid[M] > 0);
			del[S] = no[S] && (srec->uid[S] > 0);

			for (t = 0; t < 2; t++) {
				srec->aflags[t] = srec->dflags[t] = 0;
				if (srec->msg[t] && (srec->msg[t]->flags & F_DELETED))
					srec->status |= S_DEL(t);
				/* excludes (push) c.3) d.2) d.3) d.4) / (pull) b.3) d.7) d.8) d.9) */
				if (!srec->uid[t]) {
					/* b.1) / c.1) */
					debug( "  no more %s\n", str_ms[t] );
				} else if (del[1-t]) {
					/* c.4) d.9) / b.4) d.4) */
					if (srec->msg[t] && (srec->msg[t]->status & M_FLAGS) && srec->msg[t]->flags != srec->flags)
						info( "Info: conflicting changes in (%d,%d)\n", srec->uid[M], srec->uid[S] );
					if (svars->chan->ops[t] & OP_DELETE) {
						debug( "  %sing delete\n", str_hl[t] );
						svars->flags_total[t]++;
						stats( svars );
						fv = nfmalloc( sizeof(*fv) );
						fv->aux = AUX;
						fv->srec = srec;
						DRIVER_CALL(set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv ));
					} else
						debug( "  not %sing delete\n", str_hl[t] );
				} else if (!srec->msg[1-t])
					/* c.1) c.2) d.7) d.8) / b.1) b.2) d.2) d.3) */
					;
				else if (srec->uid[t] < 0)
					/* b.2) / c.2) */
					; /* handled as new messages (sort of) */
				else if (!del[t]) {
					/* a) & b.3) / c.3) */
					if (svars->chan->ops[t] & OP_FLAGS) {
						sflags = srec->msg[1-t]->flags;
						if ((srec->status & (S_EXPIRE|S_EXPIRED)) && !t)
							sflags &= ~F_DELETED;
						srec->aflags[t] = sflags & ~srec->flags;
						srec->dflags[t] = ~sflags & srec->flags;
						if (DFlags & DEBUG) {
							char afbuf[16], dfbuf[16]; /* enlarge when support for keywords is added */
							make_flags( srec->aflags[t], afbuf );
							make_flags( srec->dflags[t], dfbuf );
							debug( "  %sing flags: +%s -%s\n", str_hl[t], afbuf, dfbuf );
						}
					} else
						debug( "  not %sing flags\n", str_hl[t] );
				} /* else b.4) / c.4) */
			}
		}
	}

	if ((svars->chan->ops[S] & (OP_NEW|OP_RENEW|OP_FLAGS)) && svars->chan->max_messages) {
		/* Flagged and not yet synced messages older than the first not
		 * expired message are not counted. */
		todel = svars->ctx[S]->count + svars->new_total[S] - svars->chan->max_messages;
		debug( "scheduling %d excess messages for expiration\n", todel );
		for (tmsg = svars->ctx[S]->msgs; tmsg && todel > 0; tmsg = tmsg->next)
			if (!(tmsg->status & M_DEAD) && (srec = tmsg->srec) &&
			    ((tmsg->flags | srec->aflags[S]) & ~srec->dflags[S] & F_DELETED) &&
			    !(srec->status & (S_EXPIRE|S_EXPIRED)))
				todel--;
		debug( "%d non-deleted excess messages\n", todel );
		for (tmsg = svars->ctx[S]->msgs; tmsg; tmsg = tmsg->next) {
			if (tmsg->status & M_DEAD)
				continue;
			if (!(srec = tmsg->srec) || srec->uid[M] <= 0)
				todel--;
			else {
				nflags = (tmsg->flags | srec->aflags[S]) & ~srec->dflags[S];
				if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE|S_EXPIRED))) {
					if (nflags & F_FLAGGED)
						todel--;
					else if ((!(tmsg->status & M_RECENT) || (tmsg->flags & F_SEEN)) &&
					         (todel > 0 ||
					          ((srec->status & (S_EXPIRE|S_EXPIRED)) == (S_EXPIRE|S_EXPIRED)) ||
					          ((srec->status & (S_EXPIRE|S_EXPIRED)) && (tmsg->flags & F_DELETED)))) {
						srec->status |= S_NEXPIRE;
						debug( "  pair(%d,%d)\n", srec->uid[M], srec->uid[S] );
						todel--;
					}
				}
			}
		}
		debug( "%d excess messages remain\n", todel );
		for (srec = svars->srecs; srec; srec = srec->next) {
			if ((srec->status & (S_DEAD|S_DONE)) || !srec->msg[S])
				continue;
			nex = (srec->status / S_NEXPIRE) & 1;
			if (nex != ((srec->status / S_EXPIRED) & 1)) {
				if (nex != ((srec->status / S_EXPIRE) & 1)) {
					Fprintf( svars->jfp, "~ %d %d %d\n", srec->uid[M], srec->uid[S], nex );
					debug( "  pair(%d,%d): %d (pre)\n", srec->uid[M], srec->uid[S], nex );
					srec->status = (srec->status & ~S_EXPIRE) | (nex * S_EXPIRE);
				} else
					debug( "  pair(%d,%d): %d (pending)\n", srec->uid[M], srec->uid[S], nex );
			}
		}
	}

	debug( "synchronizing flags\n" );
	for (srec = svars->srecs; srec != *svars->osrecadd; srec = srec->next) {
		if (srec->status & (S_DEAD|S_DONE))
			continue;
		for (t = 0; t < 2; t++) {
			aflags = srec->aflags[t];
			dflags = srec->dflags[t];
			if ((t == S) && ((mvBit(srec->status, S_EXPIRE, S_EXPIRED) ^ srec->status) & S_EXPIRED)) {
				if (srec->status & S_NEXPIRE)
					aflags |= F_DELETED;
				else
					dflags |= F_DELETED;
			}
			if ((svars->chan->ops[t] & OP_EXPUNGE) && (((srec->msg[t] ? srec->msg[t]->flags : 0) | aflags) & ~dflags & F_DELETED) &&
			    (!svars->ctx[t]->conf->trash || svars->ctx[t]->conf->trash_only_new))
			{
				srec->aflags[t] &= F_DELETED;
				aflags &= F_DELETED;
				srec->dflags[t] = dflags = 0;
			}
			if (srec->msg[t] && (srec->msg[t]->status & M_FLAGS)) {
				aflags &= ~srec->msg[t]->flags;
				dflags &= srec->msg[t]->flags;
			}
			if (aflags | dflags) {
				svars->flags_total[t]++;
				stats( svars );
				fv = nfmalloc( sizeof(*fv) );
				fv->aux = AUX;
				fv->srec = srec;
				fv->aflags = aflags;
				fv->dflags = dflags;
				DRIVER_CALL(set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv ));
			} else
				flags_set_sync_p2( svars, srec, t );
		}
	}
	for (t = 0; t < 2; t++) {
		svars->drv[t]->commit( svars->ctx[t] );
		svars->state[t] |= ST_SENT_FLAGS;
		if (msgs_flags_set( svars, t ))
			return;
	}
}
Esempio n. 14
0
VALUE
rbgobj_make_flags(guint n, GType gtype)
{
    return make_flags(n, GTYPE2CLASS(gtype));
}