static void
test_set_A_unset_B_unset_A_cannot_find_A_can_find_B ()
{
  gdb_environ env;

  env.set ("GDB_SELFTEST_ENVIRON_1", "aaa");
  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_1"), "aaa") == 0);
  /* User-set environ var list must contain one element.  */
  SELF_CHECK (env.user_set_env ().size () == 1);
  SELF_CHECK (set_contains (env.user_set_env (),
			    std::string ("GDB_SELFTEST_ENVIRON_1=aaa")));

  env.set ("GDB_SELFTEST_ENVIRON_2", "bbb");
  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);

  env.unset ("GDB_SELFTEST_ENVIRON_1");
  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON_1") == NULL);
  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);

  /* The user-set environ var list must contain only one element
     now.  */
  SELF_CHECK (set_contains (env.user_set_env (),
			    std::string ("GDB_SELFTEST_ENVIRON_2=bbb")));
  SELF_CHECK (env.user_set_env ().size () == 1);
}
Beispiel #2
0
int main(int argc,
         char *argv[]) {
  void *a = new(String, "a");
  void *b = new(String, "bbb");
  void *s = new(Set);

  printf("LENGTH A: %lu\n", string_length(a));
  printf("LENGTH B: %lu\n", string_length(b));

  printf("Prev: %s\n", string_get(a));
  string_set(a, "New String");
  printf("New:  %s\n", string_get(a));

  set_add(s, a);
  set_add(s, b);

  printf("CONTAINS A: %u\n", set_contains(s, a));
  printf("CONTAINS B: %u\n", set_contains(s, b));

  printf("DROP B: %p\n", set_drop(s, b));
  printf("DROP B: %p\n", set_drop(s, b));

  printf("ADD B: %p\n", set_add(s, b));

  delete(s);
  delete(a);
  delete(b);

  return 0;
}
Beispiel #3
0
int set_contains(set_t* set, void* data)
{
	if (set == NULL)
		return 0;
	else if (set->data == data)
		return 1;
	else if (set->data > data)
		return set_contains(set->left, data);
	else
		return set_contains(set->right, data);
}
Beispiel #4
0
bool exit_status_set_test(ExitStatusSet *x, int code, int status) {

        if (exit_status_set_is_empty(x))
                return false;

        if (code == CLD_EXITED && set_contains(x->status, INT_TO_PTR(status)))
                return true;

        if (IN_SET(code, CLD_KILLED, CLD_DUMPED) && set_contains(x->signal, INT_TO_PTR(status)))
                return true;

        return false;
}
static void
test_set_unset_reset ()
{
  gdb_environ env = gdb_environ::from_host_environ ();

  /* Our test variable should already be present in the host's environment.  */
  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") != NULL);

  /* Set our test variable to another value.  */
  env.set ("GDB_SELFTEST_ENVIRON", "test");
  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "test") == 0);
  SELF_CHECK (env.user_set_env ().size () == 1);
  SELF_CHECK (env.user_unset_env ().size () == 0);

  /* And unset our test variable.  The variable still exists in the
     host's environment, but doesn't exist in our vector.  */
  env.unset ("GDB_SELFTEST_ENVIRON");
  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL);
  SELF_CHECK (env.user_set_env ().size () == 0);
  SELF_CHECK (env.user_unset_env ().size () == 1);
  SELF_CHECK (set_contains (env.user_unset_env (),
			    std::string ("GDB_SELFTEST_ENVIRON")));

  /* Re-set the test variable.  */
  env.set ("GDB_SELFTEST_ENVIRON", "1");
  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0);
}
Beispiel #6
0
// Relative complement of set1 in set2. Returns a set of elements that exist in set2 but not in set1
struct set_t *set_difference(struct set_t *set1, struct set_t *set2) {
    struct set_t *temp_set_head = NULL;
    struct set_t *temp_set_it = NULL;
    struct set_t *set_it = set2;

    // Loop through every element in set2
    while(set_it != NULL) {

        // Element must not exist in set1
        if(!set_contains(set1, set_it->value)) {
            if(temp_set_head == NULL) {
                temp_set_head = new_set(set_it->value);
                temp_set_it = temp_set_head;
            } else {
                temp_set_it->next = set_add(temp_set_head, set_it->value);
                if(temp_set_it->next != NULL)
                    temp_set_it = temp_set_it->next;
            }
        }

        set_it = set_it->next;
    }

    return temp_set_head;
}
int
main(int argc, char **argv)
{
	struct set *set;
	const char *str1 = "test1";
	const char *str2 = "test2";
	const char *str3 = "test3";

	set = set_create(badhash, string_key_equals);

	/* Unlike the hash table equivalent of this test, use an extra
	 * string so that the rehash happens at the right time.
	 */
	set_add(set, str1);
	set_add(set, str2);
	set_add(set, str3);
	set_remove(set, str2);
	set_add(set, str3);
	set_remove(set, str3);
	assert(!set_contains(set, str3));

	set_destroy(set, NULL);

	return 0;
}
Beispiel #8
0
bool is_clean_exit(int code, int status, ExitClean clean, ExitStatusSet *success_status) {

        if (code == CLD_EXITED)
                return status == 0 ||
                       (success_status &&
                        set_contains(success_status->status, INT_TO_PTR(status)));

        /* If a daemon does not implement handlers for some of the signals that's not considered an unclean shutdown */
        if (code == CLD_KILLED)
                return
                        (clean == EXIT_CLEAN_DAEMON && IN_SET(status, SIGHUP, SIGINT, SIGTERM, SIGPIPE)) ||
                        (success_status &&
                         set_contains(success_status->signal, INT_TO_PTR(status)));

        return false;
}
Beispiel #9
0
void *test(void *data)
{

  unsigned int mySeed = seed + sched_getcpu();

  long myOps = operations / nb_threads;
  long val = -1;
  int op;

  while (myOps > 0) {
    op = rand_r(&mySeed) % 100;
    if (op < update) {
      if (val == -1) {
        /* Add random value */  
        val = (rand_r(&mySeed) % range) + 1;
        if(set_add(val) == 0) {
          val = -1;
        }
      } else {
        /* Remove random value */
        int res = set_remove( val);
        val = -1;
      }
    } else {
      /* Look for random value */
      long tmp = (rand_r(&mySeed) % range) + 1;
      set_contains(tmp);
    }

    myOps--;
  }

  return NULL;
}
Beispiel #10
0
// Performs an intersection of two sets
struct set_t *set_intersection(struct set_t *set1, struct set_t *set2) {

    if(set1 == EMPTY || set2 == EMPTY)
        return EMPTY;

    struct set_t *temp_set_head = NULL;
    struct set_t *temp_set_it = NULL;
    struct set_t *set_it = set1;

    // Go through every element of set 1
    set_it = set1;
    while(set_it != NULL) {
        // See if the elements value is also in set2
        if(set_contains(set2, set_it->value)) {
            if(temp_set_head == NULL) {
                temp_set_head = new_set(set_it->value);
                temp_set_it = temp_set_head;
            } else {
                // set_add will resolve any attempts to add duplicate elements
                temp_set_it->next = set_add(temp_set_head, set_it->value);
                if(temp_set_it->next != NULL)
                    temp_set_it = temp_set_it->next;
            }
        }
        set_it = set_it->next;
    }
    return temp_set_head;
}
int
block_parameter_set_contains( block_parameter_set * p_parameter_set, block_parameter * parameter )
{
	if ( p_parameter_set == NULL || parameter == NULL )
		return 0;

	return set_contains( &p_parameter_set->parameter_set, (void*) parameter, &compare_parameters );
}
Beispiel #12
0
bool bfs_step_generic(const linear_hashing_t* hashing, queue_t* queue, set_t* visited, const struct bfs_node_struct *bfs_node_ptr)
{
	assert(hashing != NULL && queue != NULL && visited != NULL && bfs_node_ptr != NULL);
	
	unsigned int i, adj_id;
	
	node_t* node;
	edge_t* edge;
	
	struct bfs_node_struct *adj_bfs_node_ptr = NULL;
	
	/* Get node from its id */
	
	if(!linear_hashing_get(hashing, bfs_node_ptr->id, (void**)&node))
		return false;
	
	/* Get the list of all edges starting from this node */
	
	const list_t* edge_list = node_get_edge_list(node);
	
	/* Forall node neighbours... */
	
	for(i=0; i < list_size(edge_list); i++)
	{
		/* Get the neighbour's id */
		
		if(!list_get(edge_list, (void**)&edge, i))
			return false;
		
		adj_id = edge_get_id(edge);
		
		/* Check if the neighbour node is already visited */
		
		if(!set_contains(visited, adj_id))
		{
			/* If not, allocate memory for the node in the queue */
			
			if(!set_add(visited, adj_id))
				return false;
			
			if((adj_bfs_node_ptr = malloc(sizeof(struct bfs_node_struct))) == NULL)
				return false;
			
			adj_bfs_node_ptr->id = adj_id;
			adj_bfs_node_ptr->distance = bfs_node_ptr->distance + 1;
			
			/* Add the neighbour node in the queue */
			
			if(!queue_enqueue(queue, adj_bfs_node_ptr))
			{
				free(adj_bfs_node_ptr);
				return false;
			}
		}
	}
	
	return true;
}
static void
test_unset_set_empty_vector ()
{
  gdb_environ env;

  env.set ("PWD", "test");
  SELF_CHECK (strcmp (env.get ("PWD"), "test") == 0);
  SELF_CHECK (set_contains (env.user_set_env (), std::string ("PWD=test")));
  SELF_CHECK (env.user_unset_env ().size () == 0);
  /* The second element must be NULL.  */
  SELF_CHECK (env.envp ()[1] == NULL);
  SELF_CHECK (env.user_set_env ().size () == 1);
  env.unset ("PWD");
  SELF_CHECK (env.envp ()[0] == NULL);
  SELF_CHECK (env.user_set_env ().size () == 0);
  SELF_CHECK (env.user_unset_env ().size () == 1);
  SELF_CHECK (set_contains (env.user_unset_env (), std::string ("PWD")));
}
Beispiel #14
0
int main( int argc, char*argv[] )
{
	set * p_set = NULL;

	test_set_output( TEST_OUTPUT_BOTH );

	p_set = set_create();

	if ( test_assert_true ( p_set != NULL, "set creation" ) )
	{
		/* create a set with 35 elements */
		int i, *test_search;
		for( i=0; i<35; i++ )
		{
			int * test_element = (int*) malloc( sizeof(int) );
			*test_element = i;
			set_push_element( p_set, (void*) test_element );

			if ( ! test_assert_true( p_set->size == (i + 1) , "set element pushing") )
				break;

		}		

		test_search = (int*) malloc( sizeof(int) );

		/* search for an existing element */
		*test_search = 10;
		test_assert_true( set_contains( p_set, test_search, &test_set_int_compare ), "set search existing" ); 
		
		/* search for a non-existing element */
		*test_search = 56;
		test_assert_true( !set_contains( p_set, test_search, &test_set_int_compare ), "set search non-existing" ); 

		sn_free( (void**) &test_search );

		set_free( &p_set );
		
	}

	
	exit(0);
	
}
bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {

        if (code == CLD_EXITED)
                return status == 0 ||
                       (success_status &&
                       set_contains(success_status->status, INT_TO_PTR(status)));

        /* If a daemon does not implement handlers for some of the
         * signals that's not considered an unclean shutdown */
        if (code == CLD_KILLED)
                return
                        status == SIGHUP ||
                        status == SIGINT ||
                        status == SIGTERM ||
                        status == SIGPIPE ||
                        (success_status &&
                        set_contains(success_status->signal, INT_TO_PTR(status)));

        return false;
}
Beispiel #16
0
/* Attempts to add C to SET.  Returns 1 if successful, which
   will occur if and only if C was not already in SET.  Otherwise,
   returns 0. */
static int
set_add (struct set *set, int c)
{
  if (set_contains (set, c))
    return 0;

  set->which = xrealloc (set->which, sizeof *set->which * (set->n + 1));
  set->which[set->n++] = c;

  return 1;
}
Beispiel #17
0
/* the main program... */
int main(int UNUSED(argc),char UNUSED(*argv[]))
{
  SET *set;
  const char **list;
  int i;

  /* initialize */
  set=set_new();

  /* store some entries */
  set_add(set,"key1");
  set_add(set,"key2");
  set_add(set,"key3");
  set_add(set,"key2");

  /* check set contents */
  assert(set_contains(set,"key1"));
  assert(set_contains(set,"key2"));
  assert(set_contains(set,"key3"));
  assert(!set_contains(set,"key4"));
  assert(!set_contains(set,"KEY1"));

  /* loop over set contents */
  list=set_tolist(set);
  for (i=0;list[i]!=NULL;i++)
  {
    assert(isknownvalue(list[i]));
  }

  /* remove keys from the set */
  assert(isknownvalue(set_pop(set)));
  assert(isknownvalue(set_pop(set)));
  assert(isknownvalue(set_pop(set)));
  assert(set_pop(set)==NULL);

  /* free set */
  set_free(set);
  free(list);

  return 0;
}
Beispiel #18
0
// Test if every element in set1 is contained within set2
bool set_subset(struct set_t *set1, struct set_t *set2) {
    struct set_t *set_it = set1;

    while(set_it != NULL) {
        if(!set_contains(set2, set_it->value))
            return false;

        set_it = set_it->next;
    }

    return true;
}
static void
test_std_move ()
{
  gdb_environ env;
  gdb_environ env2;

  env.set ("A", "1");
  SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
  SELF_CHECK (env.user_set_env ().size () == 1);

  env2 = std::move (env);
  SELF_CHECK (env.envp ()[0] == NULL);
  SELF_CHECK (strcmp (env2.get ("A"), "1") == 0);
  SELF_CHECK (env2.envp ()[1] == NULL);
  SELF_CHECK (env.user_set_env ().size () == 0);
  SELF_CHECK (set_contains (env2.user_set_env (), std::string ("A=1")));
  SELF_CHECK (env2.user_set_env ().size () == 1);
  env.set ("B", "2");
  SELF_CHECK (strcmp (env.get ("B"), "2") == 0);
  SELF_CHECK (env.envp ()[1] == NULL);
}
Beispiel #20
0
END_TEST

/* -------------------------------------------------------------------------- */
// Set

START_TEST (test_set)
{
    set_t set;
    
    set_init(&set);
    
    uint16_t const values[] = {
        0x0392, 0xAF78, 0x8923, 0xFEAA, 0x2939, 0xFFFF, 0
    };
    
    int i = 0;
    
    do {
        fail_unless(set_add(&set, values[i]), "Could not add 0x%X to set, value number %d", values[i], i+1);
        i++;
    } while (values[i] != 0);
    
    for (int j = 0; j < SET_MAX_VALUES - i; j++) {
        fail_unless(set_add(&set, j), "Could not add 0x%X to set, value number %d", j, j+i+1);
    }
    
    fail_unless(set.length == SET_MAX_VALUES, "Pl is not at max capacity");
    
    fail_unless(set_add(&set, 0x0) == false, "Added entry after set was supposedly full");
    
    i = 0;
    do {
        fail_unless(set_contains(&set, values[i]), "Pl failed to recognize added value 0x%X", values[i]);
        i++;
    } while (values[i] != 0);
    
    fail_unless(set_contains(&set, 0xDEAD) == false, "Pl recognized a value that was not added");
}
static void
test_self_move ()
{
  gdb_environ env;

  /* Test self-move.  */
  env.set ("A", "1");
  SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
  SELF_CHECK (env.user_set_env ().size () == 1);

  /* Some compilers warn about moving to self, but that's precisely what we want
     to test here, so turn this warning off.  */
  DIAGNOSTIC_PUSH
  DIAGNOSTIC_IGNORE_SELF_MOVE
  env = std::move (env);
  DIAGNOSTIC_POP

  SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
  SELF_CHECK (strcmp (env.envp ()[0], "A=1") == 0);
  SELF_CHECK (env.envp ()[1] == NULL);
  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
  SELF_CHECK (env.user_set_env ().size () == 1);
}
int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) {
        int r;

        assert(m);

        if (set_contains(m->rules_foreign, rule)) {
                set_remove(m->rules_foreign, rule);

                r = set_ensure_allocated(&m->rules, &routing_policy_rule_hash_ops);
                if (r < 0)
                        return r;

                return set_put(m->rules, rule);
        }

        return -ENOENT;
}
Beispiel #23
0
/* Calculates the value of FIRST for the string of N grammar symbols
   at X.  Sets the result into SET. */
static void
calc_first (struct set *set, int *X, int n)
{
  int i;
  
  set_init (set);
  for (i = 0; i < n; i++)
    {
      const struct set *f = &find_symbol (X[i])->first;

      set_merge (set, f, 0);
      if (!set_contains (f, 0))
	return;
    }

  set_add (set, 0);
}
Beispiel #24
0
int set_move(intset_t *set, val_t val1, val_t val2, int transactional) {
  int result;

  if(transactional != 0) {
    TX_START(NL);
  }
  result = 0;
  if(!set_contains(set, val2, transactional)) {
    if(set_remove(set, val1, transactional)) {
      set_add(set, val2, transactional);
      result = 1;
    }
  }
  if(transactional != 0) {
    TX_END;
  }

  return result;
}
Beispiel #25
0
bool _solver_bfs_move(void *data, const maze *m, vec2 *pos) {
	bfs_data bfs = *((bfs_data *) data);
	list *neighbors;
	vec2 neigh;

	set_insert(bfs.visited, pos);
	neighbors = maze_get_neighbors(m, *pos);
	while (!list_is_empty(neighbors)) {
		list_pop_front(neighbors, &neigh);
		if (!map_contains_key(bfs.parent, &neigh)
			&& !set_contains(bfs.visited, &neigh)) {

			map_put(bfs.parent, &neigh, pos);
			list_push_back(bfs.queue, &neigh);
		}
	}
	list_destroy(neighbors);

	if (list_is_empty(bfs.queue)) {
		return false;
	}
	list_pop_front(bfs.queue, pos);
	return true;
}
Beispiel #26
0
Datei: hamt.c Projekt: 4n3w/dump
static inline struct hamt_slot item_to_slot(void *item)
{
        return (struct hamt_slot){(uint64_t)item | LEAF_MASK};
}

static inline struct hamt_node *ston(struct hamt_slot slot)
{
	return (struct hamt_node *)(uint64_t)slot.off;
}

static inline struct hamt_slot ntos(struct hamt_node *node)
{
	return (struct hamt_slot){(uint64_t)node};
}

/**************************************************************************/

static inline void *__hamt_search(struct hamt_root *root,
                                  uint128_t *hash,
                                  struct hamt_state *s)
{
        if (!is_leaf(s->ptr[s->level])) {
                struct hamt_node *node = ston(*s->ptr[s->level]);

		int slice = slice_get(*hash, s->level);
		if (set_contains(node->mask, slice)) {
                        s->hash = slice_set(s->hash, slice, s->level);
			int slot = set_slot_number(node->mask, slice);
                        s->ptr[s->level + 1] = &node->slots[slot];
                        s->level += 1;
                        return __hamt_search(root, hash, s);
                }
                return NULL;
        } else {
                void *item = to_leaf(s->ptr[s->level]);
                if (*root->hash(root->hash_ud, item) == *hash) {
                        return item;
                } else {
                        return NULL;
                }
        }
}

void *hamt_search(struct hamt_root *root, uint128_t *hash)
{
	if (unlikely(ston(root->slot) == NULL)) {
		return NULL;
	}

        struct hamt_state s;
        s.level = 0;
        s.ptr[0] = &root->slot;

	return __hamt_search(root, hash, &s);
}

/**************************************************************************/

static struct hamt_node *__hamt_new_node(struct hamt_root *root, uint64_t mask,
                                         int len)
{
	int size = sizeof(struct hamt_node) + len * sizeof(struct hamt_slot);
	struct hamt_node *node = \
		(struct hamt_node *)root->mem_alloc(size);
	assert(((unsigned long)node & ITEM_MASK) == 0);
	node->mask = mask;
	return node;
}
Beispiel #27
0
static void *test(void *data)
{
  int op, val, last = -1;
  thread_data_t *d = (thread_data_t *)data;

  /* Create transaction */
  TM_INIT_THREAD;
  /* Wait on barrier */
  barrier_cross(d->barrier);

  while (stop == 0) {
    op = rand_range(100, d->seed);
    if (op < d->update) {
      if (d->alternate) {
        /* Alternate insertions and removals */
        if (last < 0) {
          /* Add random value */
          val = rand_range(d->range, d->seed) + 1;
          if (set_add(d->set, val, d)) {
            d->diff++;
            last = val;
          }
          d->nb_add++;
        } else {
          /* Remove last value */
          if (set_remove(d->set, last, d))
            d->diff--;
          d->nb_remove++;
          last = -1;
        }
      } else {
        /* Randomly perform insertions and removals */
        val = rand_range(d->range, d->seed) + 1;
        if ((op & 0x01) == 0) {
          /* Add random value */
          if (set_add(d->set, val, d))
            d->diff++;
          d->nb_add++;
        } else {
          /* Remove random value */
          if (set_remove(d->set, val, d))
            d->diff--;
          d->nb_remove++;
        }
      }
    } else {
      /* Look for random value */
      val = rand_range(d->range, d->seed) + 1;
      if (set_contains(d->set, val, d))
        d->nb_found++;
      d->nb_contains++;
    }
  }
#ifndef TM_COMPILER
  stm_get_stats("nb_aborts", &d->nb_aborts);
  stm_get_stats("nb_aborts_1", &d->nb_aborts_1);
  stm_get_stats("nb_aborts_2", &d->nb_aborts_2);
  stm_get_stats("nb_aborts_locked_read", &d->nb_aborts_locked_read);
  stm_get_stats("nb_aborts_locked_write", &d->nb_aborts_locked_write);
  stm_get_stats("nb_aborts_validate_read", &d->nb_aborts_validate_read);
  stm_get_stats("nb_aborts_validate_write", &d->nb_aborts_validate_write);
  stm_get_stats("nb_aborts_validate_commit", &d->nb_aborts_validate_commit);
  stm_get_stats("nb_aborts_invalid_memory", &d->nb_aborts_invalid_memory);
  stm_get_stats("nb_aborts_killed", &d->nb_aborts_killed);
  stm_get_stats("locked_reads_ok", &d->locked_reads_ok);
  stm_get_stats("locked_reads_failed", &d->locked_reads_failed);
  stm_get_stats("max_retries", &d->max_retries);
#endif /* ! TM_COMPILER */
  /* Free transaction */
  TM_EXIT_THREAD;

  return NULL;
}
Beispiel #28
0
sval_t
ht_contains(ht_intset_t *set, skey_t key) 
{
  int addr = key & set->hash;
  return set_contains(&set->buckets[addr], key);
}
void PreviewLayoutLinesTool::updateLineInformation()
{
    m_lines.clear();
    const HuginBase::Panorama & pano = *(helper->GetPanoramaPtr());
    unsigned int numberOfImages = pano.getNrOfImages();
    HuginBase::UIntSet active_images = pano.getActiveImages();
    // make a line for every image pair, but set the unneeded ones as dud.
    // This is for constant look up times when we scan control points.
    m_lines.resize(numberOfImages * numberOfImages);
    unsigned int numberOfControlPoints = pano.getNrOfCtrlPoints();
    // loop over all control points to count them and get error statistics.
    for (unsigned int cpi = 0 ; cpi < numberOfControlPoints ; cpi++)
    {
        const HuginBase::ControlPoint & cp = pano.getCtrlPoint(cpi);
        unsigned int low_index, high_index;
        if (cp.image1Nr < cp.image2Nr)
        {
            low_index = cp.image1Nr;
            high_index = cp.image2Nr;
        } else {
            low_index = cp.image2Nr;
            high_index = cp.image1Nr;
        }
        // find the line.
        // We use the formula in the line below to record image numbers to each
        // line later.
        LineDetails & line = m_lines[low_index * numberOfImages + high_index];
        // update control point count.
        line.numberOfControlPoints++;
        // update error statistics
        line.totalError += cp.error;
        if (cp.error > line.worstError)
        {
            line.worstError = cp.error;
        }
    }
    
    /* Find some locations of the images. We will test if they overlap using
     *  these locations. We don't need the last image as we can always take the
     * smallest numbered image as the source of points.
     */
    /** @todo Check both ways around.
     * This only checks if points from the smallest numbered image are
     * within the largest numbered image. If the first image is huge compared to
     * the second, then it many points will miss and we might not reach the
     * target even if the second image is contained within the first.
     */
    std::vector<PosMap>  positions(pano.getNrOfImages() - 1);
    for (unsigned int i = 0; i < numberOfImages - 1; i++)
    {
        const HuginBase::SrcPanoImage & img = pano.getImage(i);
        for (unsigned int x = 0; x < SAMPLE_FREQUENCY; x++)
        {
            for (unsigned int y = 0; y < SAMPLE_FREQUENCY; y++)
            {
                // scale (x, y) so it is always within the cropped region of the
                // image.
                vigra::Rect2D c = img.getCropRect();
                /** @todo Use only points inside the circle when circular crop
                 * is used.
                 */
                double xc = double (x) / double (SAMPLE_FREQUENCY)
                                        * double(c.width()) + c.left();
                double yc = double (y) / double (SAMPLE_FREQUENCY)
                                        * double(c.height()) + c.top();
                // now look up (xc, yc) in the image, find where in the panorama
                // it ends up.
                m_transforms[i]->transformImgCoord  (
                            positions[i][x][y].x, positions[i][x][y].y,
                            xc, yc                  );
            }
        }
    }
    
    // write other line data.
    for (unsigned int i = 0; i < numberOfImages; i++)
    {
        for (unsigned int j = 0; j < numberOfImages; j++)
        {
            LineDetails & line = m_lines[i * numberOfImages + j];
            line.image1 = i;
            line.image2 = j;
            /// test if the line should be visible.
            if (!(set_contains(active_images, i) &&
                  set_contains(active_images, j)))
            {
                // At least one of the images is hidden, so don't show the line.
                line.dud = true;
            }
            else if (line.numberOfControlPoints > 0)
            {
                line.dud = false;
            } else if (i >= j) {
                // We only use lines where image1 is the lowest numbered image.
                // We don't bother with lines from one image to the same one.
                line.dud = true;
            } else {
                // test overlapping regions.
                HuginBase::PTools::Transform transform;
                ViewState & viewState = *helper->GetViewStatePtr();
                HuginBase::SrcPanoImage & src = *viewState.GetSrcImage(j);
                transform.createTransform(src, *(viewState.GetOptions()));
                unsigned int overlapingSamples = 0;
                for (unsigned int x = 0; x < SAMPLE_FREQUENCY; x++)
                {
                    for (unsigned int y = 0; y < SAMPLE_FREQUENCY; y++)
                    {
                        // check if mapping a point that was found earilier to
                        // be inside an image in panorama space is inside the
                        // other image when transformed from panorama to image.
                        double dx, dy;
                        transform.transformImgCoord (
                                        dx, dy,
                                        positions[i][x][y].x,
                                        positions[i][x][y].y
                                                    );
                        if (src.isInside(vigra::Point2D((int) dx, (int) dy)))
                        {
                            // they overlap
                            overlapingSamples++;
                        }
                    }
                }
                // If the overlap isn't big enough, the line isn't used.
                line.dud = (overlapingSamples < MIN_SAMPLE_OVERLAPS);
            }
            
            if (!line.dud)
            {
                line.arc = GreatCircleArc(m_imageCentresSpherical[i].x,
                                          m_imageCentresSpherical[i].y,
                                          m_imageCentresSpherical[j].x,
                                          m_imageCentresSpherical[j].y,
                                          *(helper->GetVisualizationStatePtr()));
            }
        }
    }
}
Beispiel #30
0
/* Use this function only if you do not have direct access to /proc/self/mountinfo but the caller can open it
 * for you. This is the case when /proc is masked or not mounted. Otherwise, use bind_remount_recursive. */
int bind_remount_recursive_with_mountinfo(
                const char *prefix,
                unsigned long new_flags,
                unsigned long flags_mask,
                char **blacklist,
                FILE *proc_self_mountinfo) {

        _cleanup_set_free_free_ Set *done = NULL;
        _cleanup_free_ char *cleaned = NULL;
        int r;

        assert(proc_self_mountinfo);

        /* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already
         * mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
         * operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to
         * all submounts we can access, too. When mounts are stacked on the same mount point we only care for each
         * individual "top-level" mount on each point, as we cannot influence/access the underlying mounts anyway. We
         * do not have any effect on future submounts that might get propagated, they migt be writable. This includes
         * future submounts that have been triggered via autofs.
         *
         * If the "blacklist" parameter is specified it may contain a list of subtrees to exclude from the
         * remount operation. Note that we'll ignore the blacklist for the top-level path. */

        cleaned = strdup(prefix);
        if (!cleaned)
                return -ENOMEM;

        path_simplify(cleaned, false);

        done = set_new(&path_hash_ops);
        if (!done)
                return -ENOMEM;

        for (;;) {
                _cleanup_set_free_free_ Set *todo = NULL;
                bool top_autofs = false;
                char *x;
                unsigned long orig_flags;

                todo = set_new(&path_hash_ops);
                if (!todo)
                        return -ENOMEM;

                rewind(proc_self_mountinfo);

                for (;;) {
                        _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
                        int k;

                        k = fscanf(proc_self_mountinfo,
                                   "%*s "       /* (1) mount id */
                                   "%*s "       /* (2) parent id */
                                   "%*s "       /* (3) major:minor */
                                   "%*s "       /* (4) root */
                                   "%ms "       /* (5) mount point */
                                   "%*s"        /* (6) mount options (superblock) */
                                   "%*[^-]"     /* (7) optional fields */
                                   "- "         /* (8) separator */
                                   "%ms "       /* (9) file system type */
                                   "%*s"        /* (10) mount source */
                                   "%*s"        /* (11) mount options (bind mount) */
                                   "%*[^\n]",   /* some rubbish at the end */
                                   &path,
                                   &type);
                        if (k != 2) {
                                if (k == EOF)
                                        break;

                                continue;
                        }

                        r = cunescape(path, UNESCAPE_RELAX, &p);
                        if (r < 0)
                                return r;

                        if (!path_startswith(p, cleaned))
                                continue;

                        /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall
                         * operate on. */
                        if (!path_equal(cleaned, p)) {
                                bool blacklisted = false;
                                char **i;

                                STRV_FOREACH(i, blacklist) {

                                        if (path_equal(*i, cleaned))
                                                continue;

                                        if (!path_startswith(*i, cleaned))
                                                continue;

                                        if (path_startswith(p, *i)) {
                                                blacklisted = true;
                                                log_debug("Not remounting %s blacklisted by %s, called for %s", p, *i, cleaned);
                                                break;
                                        }
                                }
                                if (blacklisted)
                                        continue;
                        }

                        /* Let's ignore autofs mounts.  If they aren't
                         * triggered yet, we want to avoid triggering
                         * them, as we don't make any guarantees for
                         * future submounts anyway.  If they are
                         * already triggered, then we will find
                         * another entry for this. */
                        if (streq(type, "autofs")) {
                                top_autofs = top_autofs || path_equal(cleaned, p);
                                continue;
                        }

                        if (!set_contains(done, p)) {
                                r = set_consume(todo, p);
                                p = NULL;
                                if (r == -EEXIST)
                                        continue;
                                if (r < 0)
                                        return r;
                        }
                }

                /* If we have no submounts to process anymore and if
                 * the root is either already done, or an autofs, we
                 * are done */
                if (set_isempty(todo) &&
                    (top_autofs || set_contains(done, cleaned)))
                        return 0;

                if (!set_contains(done, cleaned) &&
                    !set_contains(todo, cleaned)) {
                        /* The prefix directory itself is not yet a mount, make it one. */
                        if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
                                return -errno;

                        orig_flags = 0;
                        (void) get_mount_flags(cleaned, &orig_flags);
                        orig_flags &= ~MS_RDONLY;

                        if (mount(NULL, cleaned, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
                                return -errno;

                        log_debug("Made top-level directory %s a mount point.", prefix);

                        r = set_put_strdup(done, cleaned);
                        if (r < 0)
                                return r;
                }

                while ((x = set_steal_first(todo))) {

                        r = set_consume(done, x);
                        if (IN_SET(r, 0, -EEXIST))
                                continue;
                        if (r < 0)
                                return r;

                        /* Deal with mount points that are obstructed by a later mount */
                        r = path_is_mount_point(x, NULL, 0);
                        if (IN_SET(r, 0, -ENOENT))
                                continue;
                        if (IN_SET(r, -EACCES, -EPERM)) {
                                /* Even if root user invoke this, submounts under private FUSE or NFS mount points
                                 * may not be acceessed. E.g.,
                                 *
                                 * $ bindfs --no-allow-other ~/mnt/mnt ~/mnt/mnt
                                 * $ bindfs --no-allow-other ~/mnt ~/mnt
                                 *
                                 * Then, root user cannot access the mount point ~/mnt/mnt.
                                 * In such cases, the submounts are ignored, as we have no way to manage them. */
                                log_debug_errno(r, "Failed to determine '%s' is mount point or not, ignoring: %m", x);
                                continue;
                        }
                        if (r < 0)
                                return r;

                        /* Try to reuse the original flag set */
                        orig_flags = 0;
                        (void) get_mount_flags(x, &orig_flags);
                        orig_flags &= ~MS_RDONLY;

                        if (mount(NULL, x, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
                                return -errno;

                        log_debug("Remounted %s read-only.", x);
                }
        }