[GRASS-dev] Re: bug in Vect_cidx_find_next() ?

Moritz Lennert mlennert at club.worldonline.be
Mon Oct 9 12:26:19 EDT 2006


Coming back to this discussion...

Radim Blazek wrote:
> On 9/29/06, Moritz Lennert <mlennert at club.worldonline.be> wrote:
>> Radim Blazek wrote:
>> > Yes,
>> > it seems to be bug, I think that on row 296 in cindex.c
>> > the requested cat should also be checked, not only the type.
>> > But I am tired now, please check it twice.
>>
>> Changing that line into
>>
>> if ( ci->cat[cat_index][0] == cat && ci->cat[cat_index][1] & type_mask )
>>
>> works. Thanks !
>>
>> But I don't really understand how this could happen, as I thought the
>> following lines (286-288) should take care of this before:
>>
>> while ( cat_index > start_index ) {
>>      if ( ci->cat[cat_index-1][0] != cat ) {
>>         break;
> 
> No, this goes down to lowest index of this cat because bsearch
> does not return the first item.

But what I don't understand is how we even get to a cat_index value 
which corresponds to a feature with the wrong cat ?

The bsearch should find an object with the right cat and since the cat 
index is sorted everything below that object should have the right cat 
until we reach a wrong cat through above while loop.

I have no problem just committing above fix and using your suggestions 
below, but I would like to understand how the problem could come about.

See below for similar question.

> 
> To simplify use of cat index in modules I would suggest 2 new functions
> (not tested/compiled):
> 
> void Vect_cidx_find_lines ( struct Map_info *Map, int layer, int cat,
>                                 struct ilist *lines )
> {
>      int type, line;
>      struct Cat_index *ci;
> 
>      Vect_reset_list ( lines );
>      int field_index = Vect_cidx_get_field_index ( Map, layer );
>      ci = &(Map->plus.cidx[field_index]);
> 
>      int idx = Vect_cidx_find_next ( Map, field_index, cat, 0,
>                                  GV_LINES|GV_POINTS, &type, &line );
> 
>      if ( idx == -1 ) return;
> 
>      do {
>          if ( !(ci->cat[idx][1] & GV_LINES|GV_POINTS)
>               ||  ci->cat[idx][0]  != cat )


Again, if Vect_cidx_find_next works correctly, how could this happen ? 
If it does this would be a bug in Vect_cidx_find_next, or ?

>          {
>               break;
>           }
>           Vect_list_append ( lines, ci->cat[idx][2] );
>           idx++;
>       } while (   idx < ci->n_cats );
>       return;
> }
> 
> and similarly Vect_cidx_find_areas, then in module:
> 
> struct ilist *lines = Vect_new_list();
> 
> Vect_cidx_find_lines ( Map, layer, cat, lines );
> for ( i = 0; i < lines->n_values; i++ )
> {
>    line = lines->value[i];
>    Vect_read_line ( Map, Points, NULL, line );
> }
> 
> Radim

Thanks !

Moritz




More information about the grass-dev mailing list