Пример #1
0
void	pr_int(t_conv *conv)
{
	int		signoffset;
	char	fillchar;

	pre_int(conv);
	if (conv->precision_on || conv->minus)
		conv->zero = 0;
	fillchar = conv->zero && !conv->minus ? '0' : ' ';
	signoffset = fillchar == '0' && (conv->str[0] == '-' || \
		conv->plus || conv->space) ? 1 : 0;
	while (conv->precision_on && (int)ft_strlen(conv->str) < \
			conv->precision + (conv->str[0] == '-'))
		conv->str = insert_at(conv->str, '0', (conv->str[0] == '-'));
	if (conv->plus)
		conv->str = insert_at(conv->str, '+', 0);
	else if (conv->space)
		conv->str = insert_at(conv->str, ' ', 0);
	if ((conv->specifier == 'x' || conv->specifier == 'X') \
		&& conv->hash && fillchar == '0')
		signoffset = 2;
	while ((int)ft_strlen(conv->str) < conv->width)
		conv->str = insert_at(conv->str, fillchar, \
			signoffset + conv->minus * ft_strlen(conv->str));
}
Пример #2
0
void	pre_int(t_conv *conv)
{
	if (conv->str[0] == '-')
	{
		conv->plus = 0;
		conv->space = 0;
	}
	if (conv->precision_on && conv->precision == 0 && ft_atoi(conv->str) == 0)
	{
		conv->plus = 0;
		conv->space = 0;
		free(conv->str);
		conv->str = ft_strdup("");
		if (conv->specifier == 'x' || conv->specifier == 'X')
			return ;
	}
	if (conv->hash && (ft_atoi(conv->str) != 0 || conv->str[0] == 0))
	{
		conv->plus = 0;
		conv->space = 0;
		conv->str = insert_at(conv->str, '0', 0);
		if (conv->specifier == 'x' || conv->specifier == 'X')
			conv->str = insert_at(conv->str, conv->specifier, 1);
	}
}
Пример #3
0
int main(){
    List list;
    List list2;
    int i;
    
    init_list( &list );
    printf( "Empty: %d\n", empty_list( list ) );
    for( i = 1; i <= 5; i++ ){
        append_node( &i, sizeof( int ), list );
        printf( "Length: %d | ", length( list ) );
        print_list( list );
    }
    for( i = 6; i <= 10; i++ ){
        insert_front( &i, sizeof( int ), list );
        printf( "Length: %d | ", length( list ) );
        print_list( list );
    }
    printf( "Empty: %d\n", empty_list( list ) );
    printf( "First: %d\n", get_int( list_op_first( list ) -> data ) );
    printf( "Last:  %d\n", get_int( list_op_last( list ) -> data ) );
    printf( "Second to last: %d\n", get_int( list_op_prev( list_op_last( list ), list ) -> data ) );
    printf( "Second element: %d\n", get_int( get_elem_at( 1, list ) -> data ) );
    
    place_after( &i, sizeof( int ), get_elem_at( 1, list ), list );
    print_list( list );
    i++;
    insert_at( &i, sizeof( int ), 2, list );
    print_list( list );
    i++;
    insert_at( &i, sizeof( int ), 0, list );
    print_list( list );
    
    init_list( &list2 );
    for( i = 100; i > 95; i-- ){
        insert_front( &i, sizeof( int ), list2 );
    }
    append_list( list, &list2 );
    free( list2 );
    print_list( list );
    
    printf( "Erasing 5th element...\n" );
    erase_at( 4, list );
    print_list( list );
    printf( "Erasing 1st element...\n" );
    erase_at( 0, list );
    print_list( list );
    printf( "Erasing last element...\n" );
    erase_node( list_op_last( list ), list );
    print_list( list );
    printf( "Erasing 3rd element...\n" );
    erase_node( get_elem_at( 2, list ), list );
    print_list( list );
    
    clear_list( &list );
    
    return 0;
}
Пример #4
0
//------ BEGIN OF FUNCTION DynArray::linkin_sort_scan_from_bottom ----------//
//
// Description : linkin a entry to a sorted link list
//
// Note    : init_sort() must be called first, before using sorting function
// Warning : DynArrayB (version B) can't use this function
//
// Syntax      : linkin_sort_scan_from_bottom(<void*>,<int>,<char>)
//
// <void*> = the structure buffer pointer
//
// Note : use DynArray::seek() to search quickly if the whole DynArray is
//        built up with linkin_sort_scan_from_bottom()
//
// WARNING : After calling linkin() all pointers to the linklist body
//           should be updated, because mem_resize() will move the body memory
//
void DynArray::linkin_sort_scan_from_bottom(void* varPtr) {
    err_when( sort_offset < 0 );

    int   cmpRet;
    char* varData,*bodyChar;

    for( int recNo=last_ele ; recNo>0 ; recNo-- ) {
	//-------- comparsion ---------//

	switch( sort_type ) {
	case SORT_INT:                              // <int>
	    cmpRet   = *((int*)((char*)varPtr+sort_offset)) >
		*((int*)((char*)get()+sort_offset));
	    break;

	case SORT_SHORT:                            // <short>
	    cmpRet   = *((short*)((char*)varPtr+sort_offset)) >
		*((short*)((char*)get()+sort_offset));
	    break;

	case SORT_CHAR:                             // <char>
	    cmpRet   = *((char*)((char*)varPtr+sort_offset)) >
		*((char*)((char*)get()+sort_offset));
	    break;

	case SORT_CHAR_PTR:                         // <char*>
	    varData  = *( (char**)((char*)varPtr + sort_offset) );
	    bodyChar = *( (char**)((char*)get() + sort_offset) );

	    err_when( !varData || !bodyChar );

	    cmpRet   = strcmp( varData, bodyChar );
	    break;

	case SORT_CHAR_STR:                         // <char[]>
	    varData  = (char*)varPtr + sort_offset ;
	    bodyChar = (char*)get() + sort_offset ;

	    err_when( !varData || !bodyChar );

	    cmpRet   = strcmp( varData, bodyChar );
	    break;
	}

	//---- if equal then linkin -----------//

	if( cmpRet >= 0 ) {
	    insert_at( last_ele+1, varPtr) ;
	    return;
	}
    }

    insert_at( 1, varPtr);                          // insert at the top
}
Пример #5
0
//--------- Begin of function SpriteArray::add_sorted ---------//
//
// Add the sprite into the array in a sorted order.
//
// <Sprite*> spritePtr - pointer to the sprite to be added
//
// Note: it does not call Sprite::init_recno() as it is supposed to be used by disp_sprite_array
//		   only and sprites to be added are existing sprites only.
//
// return : <int> - the recno of the newly added sprite in SpriteArray.
//
void SpriteArray::add_sorted(Sprite *newSprite)
{
	int l=0, r=size(), x=0;
	int addY  = newSprite->abs_y2;
	int testY = addY + 1;

	//---------------------------------------------------------------------//
	// Use a binary search to find the right location to add the new sprite.
	//---------------------------------------------------------------------//

	while (r > l)
	{
	  x = (l + r) / 2;

	  testY = operator[](x+1)->abs_y2;   // the one to be compared with the adding one.

	  if (addY < testY)
		  r = x;
	  else
		  l = x + 1;

	  if (addY == testY)
		  break;
	}

	if (addY >= testY)
		x++;

	insert_at(x+1, &newSprite);
}
Пример #6
0
void Inventory::copyToInventory(Object &obj) {
	InventoryItem invItem;
	invItem._name = obj._name;
	invItem._description = obj._description;
	invItem._examine = obj._examine;
	invItem._lookFlag = obj._lookFlag;
	invItem._requiredFlag = obj._requiredFlag[0];

	insert_at(_holdings, invItem);
	++_holdings;
}
Пример #7
0
Patricia::status
Patricia::insert(Trieable const& val)
{
  /* find biggest prefix of data in val */
  internal_search_result const found =
    internal_search(val, this->patricia.root);
  if (0 == found.status) /* exact match found, val is a duplicate */
  {
    status const result = { EEXIST };
    return result;
  }

  if (0 == val.len()) /* special case for root node */
  {
    assert(ENODATA == found.status); /* or we would have a match */
    return insert_at(found.prefix, val.copy());
  }
  if (NULL == found.last)
  {
    return insert_between(found.prefix, found.last,
        new Patricia::node, val.copy());
  }
  Patricia::node* const data = first_data_node(found.last);
  assert(NULL != data); /* else found.last would be NULL */
  Trieable::difference const diff =
    data->val->diff(val, found.prefix->branch);
  if (val.len() == diff.bit) /* val is a prefix of a node */
  {
    assert(val.len() <= found.last->branch);
    if (val.len() < found.last->branch)
    {
      return insert_between(found.last->parent, found.last,
          new Patricia::node, val.copy());
    }
    assert(NULL == found.last->val); /* or we would find a match */
    return insert_at(found.last, val.copy());
  }
  return branch_at(found.last, new Patricia::node,
      new Patricia::node, val.copy());
}
Пример #8
0
void
bridge_compound_rep::notify_insert (path p, tree u) {
  // cout << "Insert " << p << ", " << u << " in " << st << "\n";
  ASSERT (!is_nil (p), "nil path");
  if (is_atom (p) || is_nil (body)) bridge_rep::notify_insert (p, u);
  else {
    // bool mp_flag= is_multi_paragraph (st);
    if (is_func (fun, XMACRO, 2))
      notify_macro (MACRO_INSERT, fun[0]->label, -1, p, u);
    else if (is_applicable (fun) && (p->item < N(fun)))
      notify_macro (MACRO_INSERT, fun[p->item-delta]->label, -1, p->next, u);
    st= insert_at (st, p, u);
    // if (mp_flag != is_multi_paragraph (st)) valid= false;
  }
  status= CORRUPTED;
}
Пример #9
0
/**
 * Tworzy wszytskie możliwe modyfikacje słowa 'word' według zasad
 * ustalonych dla dictionary_hints.
 * @param[in] dict Słownik.
 * @param[in] word Słowo.
 * @param[in,out] hints_size Ilość podpowiedzi.
 * @param[in,out] output Wskaźnik na tablicę podpowiedzi.
 */
static void possible_hints(const struct dictionary *dict, const wchar_t *word,
						   int **hints_size, wchar_t ***output)
{
	const wchar_t * alphabet = create_alphabet(dict);
	wchar_t *hints[HINTS_SIZE];
	int size = 0;
	for (size_t i = 0; i < (wcslen(word) + 1); i++)
	{
		wchar_t *h1 = malloc(wcslen(word) * sizeof(wchar_t *));
		wcscpy(h1, word);
		delete_at(h1, i, wcslen(word));
		hints[size] = h1;
		size++;
	}
	for (size_t i = 0; i < wcslen(word); i++)
		for (int j = 0; alphabet[j]; j++)
		{
			wchar_t *h2 = malloc((wcslen(word) + 1) * sizeof(wchar_t *));
			wcscpy(h2, word);
			replace_at(h2, alphabet[j], i, wcslen(word));
			hints[size] = h2;
			size++;
		}

	for (size_t i = 0; i <= wcslen(word); i++)
		for (int j = 0; alphabet[j]; j++)
		{
			wchar_t *h3 = malloc((wcslen(word) + 2) * sizeof(wchar_t *));
			h3[0] = L'\0';
			wchar_t c[2];
			c[0] = alphabet[j];
			c[1] = L'\0';
			insert_at(word, c, i, wcslen(word), &h3);
			hints[size] = h3;
			size++;
		}
	*hints_size = &size;
	qsort(hints, size, sizeof(wchar_t *), compare);
	*output = hints;
}
Пример #10
0
/* actual insert: returns true -> insert ok or key found, false -> alloc failure */
bool cbtree_insert(struct CBTree *tree, void *obj)
{
	const void *key, *old_key;
	unsigned newbit, klen, old_klen;
	void *old_obj;

	if (!tree->root)
		return insert_first(tree, obj);

	/* current key */
	klen = get_key(tree, obj, &key);

	/* nearest key in tree */
	old_obj = raw_lookup(tree, key, klen);
	old_klen = get_key(tree, old_obj, &old_key);

	/* first differing bit is the target position */
	newbit = find_crit_bit(key, klen, old_key, old_klen);
	if (newbit == SAME_KEY)
		return true;
	return insert_at(tree, newbit, key, klen, obj);
}
Пример #11
0
// Insert the given utf8 string into the rope at the specified position.
static ROPE_RESULT rope_insert_at_iter(rope *r, rope_node *e, rope_iter *iter, const uint8_t *str) {
  // iter.offset contains how far (in characters) into the current element to skip.
  // Figure out how much that is in bytes.
  size_t offset_bytes = 0;
  // The insertion offset into the destination node.
  size_t offset = iter->s[0].skip_size;
  if (offset) {
    assert(offset <= e->nexts[0].skip_size);
    offset_bytes = count_bytes_in_utf8(e->str, offset);
  }

  // We might be able to insert the new data into the current node, depending on
  // how big it is. We'll count the bytes, and also check that its valid utf8.
  ssize_t num_inserted_bytes = bytelen_and_check_utf8(str);
  if (num_inserted_bytes == -1) return ROPE_INVALID_UTF8;

  // Can we insert into the current node?
  bool insert_here = e->num_bytes + num_inserted_bytes <= ROPE_NODE_STR_SIZE;

  // Can we insert into the subsequent node?
  rope_node *next = NULL;
  if (!insert_here && offset_bytes == e->num_bytes) {
    next = e->nexts[0].node;
    // We can insert into the subsequent node if:
    // - We can't insert into the current node
    // - There _is_ a next node to insert into
    // - The insert would be at the start of the next node
    // - There's room in the next node
    if (next && next->num_bytes + num_inserted_bytes <= ROPE_NODE_STR_SIZE) {
      offset = offset_bytes = 0;
      for (int i = 0; i < next->height; i++) {
        iter->s[i].node = next;
        // tree offset nodes will not be used.
      }
      e = next;

      insert_here = true;
    }
  }

  if (insert_here) {
    // First move the current bytes later on in the string.
    if (offset_bytes < e->num_bytes) {
      memmove(&e->str[offset_bytes + num_inserted_bytes],
              &e->str[offset_bytes],
              e->num_bytes - offset_bytes);
    }

    // Then copy in the string bytes
    memcpy(&e->str[offset_bytes], str, num_inserted_bytes);
    e->num_bytes += num_inserted_bytes;

    r->num_bytes += num_inserted_bytes;
    size_t num_inserted_chars = strlen_utf8(str);
    r->num_chars += num_inserted_chars;

    // .... aaaand update all the offset amounts.
#if ROPE_WCHAR
    size_t num_inserted_wchars = count_wchars_in_utf8(str, num_inserted_chars);
    update_offset_list(r, iter, num_inserted_chars, num_inserted_wchars);
#else
    update_offset_list(r, iter, num_inserted_chars);
#endif

  } else {
    // There isn't room. We'll need to add at least one new node to the rope.

    // If we're not at the end of the current node, we'll need to remove
    // the end of the current node's data and reinsert it later.
    size_t num_end_chars, num_end_bytes = e->num_bytes - offset_bytes;
    if (num_end_bytes) {
      // We'll pretend like the character have been deleted from the node, while leaving
      // the bytes themselves there (for later).
      e->num_bytes = offset_bytes;
      num_end_chars = e->nexts[0].skip_size - offset;
#if ROPE_WCHAR
      size_t num_end_wchars = count_wchars_in_utf8(&e->str[offset_bytes], num_end_chars);
      update_offset_list(r, iter, -num_end_chars, -num_end_wchars);
#else
      update_offset_list(r, iter, -num_end_chars);
#endif

      r->num_chars -= num_end_chars;
      r->num_bytes -= num_end_bytes;
    }

    // Now we insert new nodes containing the new character data. The data must be broken into
    // pieces of with a maximum size of ROPE_NODE_STR_SIZE. Node boundaries must not occur in the
    // middle of a utf8 codepoint.
    size_t str_offset = 0;
    while (str_offset < num_inserted_bytes) {
      size_t new_node_bytes = 0;
      size_t new_node_chars = 0;

      while (str_offset + new_node_bytes < num_inserted_bytes) {
        size_t cs = codepoint_size(str[str_offset + new_node_bytes]);
        if (cs + new_node_bytes > ROPE_NODE_STR_SIZE) {
          break;
        } else {
          new_node_bytes += cs;
          new_node_chars++;
        }
      }

      insert_at(r, iter, &str[str_offset], new_node_bytes, new_node_chars);
      str_offset += new_node_bytes;
    }

    if (num_end_bytes) {
      insert_at(r, iter, &e->str[offset_bytes], num_end_bytes, num_end_chars);
    }
  }

  return ROPE_OK;
}
Пример #12
0
/*
 * Splits a node by creating a sibling node and shifting half the nodes
 * contents across.  Assumes there is a parent node, and it has room for
 * another child.
 *
 * Before:
 *	  +--------+
 *	  | Parent |
 *	  +--------+
 *	     |
 *	     v
 *	+----------+
 *	| A ++++++ |
 *	+----------+
 *
 *
 * After:
 *		+--------+
 *		| Parent |
 *		+--------+
 *		  |	|
 *		  v	+------+
 *	    +---------+	       |
 *	    | A* +++  |	       v
 *	    +---------+	  +-------+
 *			  | B +++ |
 *			  +-------+
 *
 * Where A* is a shadow of A.
 */
static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
			       unsigned parent_index, uint64_t key)
{
	int r;
	size_t size;
	unsigned nr_left, nr_right;
	struct dm_block *left, *right, *parent;
	struct btree_node *ln, *rn, *pn;
	__le64 location;

	left = shadow_current(s);

	r = new_block(s->info, &right);
	if (r < 0)
		return r;

	ln = dm_block_data(left);
	rn = dm_block_data(right);

	nr_left = le32_to_cpu(ln->header.nr_entries) / 2;
	nr_right = le32_to_cpu(ln->header.nr_entries) - nr_left;

	ln->header.nr_entries = cpu_to_le32(nr_left);

	rn->header.flags = ln->header.flags;
	rn->header.nr_entries = cpu_to_le32(nr_right);
	rn->header.max_entries = ln->header.max_entries;
	rn->header.value_size = ln->header.value_size;
	memcpy(rn->keys, ln->keys + nr_left, nr_right * sizeof(rn->keys[0]));

	size = le32_to_cpu(ln->header.flags) & INTERNAL_NODE ?
		sizeof(uint64_t) : s->info->value_type.size;
	memcpy(value_ptr(rn, 0), value_ptr(ln, nr_left),
	       size * nr_right);

	/*
	 * Patch up the parent
	 */
	parent = shadow_parent(s);

	pn = dm_block_data(parent);
	location = cpu_to_le64(dm_block_location(left));
	__dm_bless_for_disk(&location);
	memcpy_disk(value_ptr(pn, parent_index),
		    &location, sizeof(__le64));

	location = cpu_to_le64(dm_block_location(right));
	__dm_bless_for_disk(&location);

	r = insert_at(sizeof(__le64), pn, parent_index + 1,
		      le64_to_cpu(rn->keys[0]), &location);
	if (r)
		return r;

	if (key < le64_to_cpu(rn->keys[0])) {
		unlock_block(s->info, right);
		s->nodes[1] = left;
	} else {
		unlock_block(s->info, left);
		s->nodes[1] = right;
	}

	return 0;
}
Пример #13
0
// Insert the given utf8 string into the rope at the specified position.
void rope_insert(rope *r, size_t pos, const uint8_t *str) {
  assert(r);
  assert(str);
#ifdef DEBUG
  _rope_check(r);
#endif
  pos = MIN(pos, r->num_chars);

  // There's a good chance we'll have to rewrite a bunch of next pointers and a bunch
  // of offsets. This variable will store pointers to the elements which need to
  // be changed.
  rope_node *nodes[UINT8_MAX];
  size_t tree_offsets[UINT8_MAX];

  // This is the number of characters to skip in the current node.
  size_t offset;
  
  // First we need to search for the node where we'll insert the string.
  rope_node *e = go_to_node(r, pos, &offset, nodes, tree_offsets);
  
  // offset contains how far (in characters) into the current element to skip.
  // Figure out how much that is in bytes.
  size_t offset_bytes = 0;
  if (e && offset) {
    assert(offset <= e->num_bytes);
    offset_bytes = count_bytes_in_chars(e->str, offset);
  }
  
  // Maybe we can insert the characters into the current node?
  size_t num_inserted_bytes = strlen((char *)str);

  // Can we insert into the current node?
  bool insert_here = e && e->num_bytes + num_inserted_bytes <= ROPE_NODE_STR_SIZE;
  
  // Can we insert into the subsequent node?
  bool insert_next = false;
  rope_node *next = NULL;
  if (!insert_here) {
    next = e ? e->nexts[0].node : (r->num_chars ? r->heads[0].node : NULL);
    // We can insert into the subsequent node if:
    // - We can't insert into the current node
    // - There _is_ a next node to insert into
    // - The insert would be at the start of the next node
    // - There's room in the next node
    insert_next = next
        && (e == NULL || offset_bytes == e->num_bytes)
        && next->num_bytes + num_inserted_bytes <= ROPE_NODE_STR_SIZE;
  }
  
  if (insert_here || insert_next) {
    if (insert_next) {
      offset = offset_bytes = 0;
      for (int i = 0; i < next->height; i++) {
        nodes[i] = next;
        // tree offset nodes not used.
      }
      e = next;
    }
    
    // First move the current bytes later on in the string.
    if (offset_bytes < e->num_bytes) {
      memmove(&e->str[offset_bytes + num_inserted_bytes],
              &e->str[offset_bytes],
              e->num_bytes - offset_bytes);
    }
    
    // Then copy in the string bytes
    memcpy(&e->str[offset_bytes], str, num_inserted_bytes);
    e->num_bytes += num_inserted_bytes;
    
    r->num_bytes += num_inserted_bytes;
    size_t num_inserted_chars = strlen_utf8(str);
    r->num_chars += num_inserted_chars;
    
    // .... aaaand update all the offset amounts.
    update_offset_list(r, nodes, num_inserted_chars);
  } else {
    // There isn't room. We'll need to add at least one new node to the rope.
    
    // If we're not at the end of the current node, we'll need to remove
    // the end of the current node's data and reinsert it later.
    size_t num_end_bytes = 0, num_end_chars;
    if (e) {
      num_end_bytes = e->num_bytes - offset_bytes;
      e->num_bytes = offset_bytes;
      if (num_end_bytes) {
        // Count out characters.
        num_end_chars = e->nexts[0].skip_size - offset;
        update_offset_list(r, nodes, -num_end_chars);
        
        r->num_chars -= num_end_chars;
        r->num_bytes -= num_end_bytes;
      }
    }
    
    // Now, we insert new node[s] containing the data. The data must
    // be broken into pieces of with a maximum size of ROPE_NODE_STR_SIZE.
    // Node boundaries do not occur in the middle of a utf8 codepoint.
    size_t str_offset = 0;
    while (str_offset < num_inserted_bytes) {
      size_t new_node_bytes = 0;
      size_t new_node_chars = 0;
      
      while (str_offset + new_node_bytes < num_inserted_bytes) {
        size_t cs = codepoint_size(str[str_offset + new_node_bytes]);
        if (cs + new_node_bytes > ROPE_NODE_STR_SIZE) {
          break;
        } else {
          new_node_bytes += cs;
          new_node_chars++;
        }
      }
      
      insert_at(r, pos, &str[str_offset], new_node_bytes, new_node_chars, nodes, tree_offsets);
      pos += new_node_chars;
      str_offset += new_node_bytes;
    }
    
    if (num_end_bytes) {
      insert_at(r, pos, &e->str[offset_bytes], num_end_bytes, num_end_chars, nodes, tree_offsets);
    }
  }
  
#ifdef DEBUG
  _rope_check(r);
#endif
}