LCOV - code coverage report
Current view: top level - languages - steminternal.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core r Lines: 203 216 94.0 %
Date: 2011-08-21 Functions: 21 26 80.8 %
Branches: 174 200 87.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file steminternal.cc
       2                 :            :  *  @brief Base class for implementations of stemming algorithms
       3                 :            :  */
       4                 :            : /* Derived from snowball's runtime/api.c:
       5                 :            :  *
       6                 :            :  * Copyright (c) 2001, Dr Martin Porter
       7                 :            :  * Copyright (c) 2004,2005, Richard Boulton
       8                 :            :  * Copyright (c) 2006,2007,2008,2009 Olly Betts
       9                 :            :  * All rights reserved.
      10                 :            :  *
      11                 :            :  * Redistribution and use in source and binary forms, with or without
      12                 :            :  * modification, are permitted provided that the following conditions are met:
      13                 :            :  *
      14                 :            :  *   * Redistributions of source code must retain the above copyright notice,
      15                 :            :  *     this list of conditions and the following disclaimer.
      16                 :            :  *
      17                 :            :  *   * Redistributions in binary form must reproduce the above copyright
      18                 :            :  *     notice, this list of conditions and the following disclaimer in the
      19                 :            :  *     documentation and/or other materials provided with the distribution.
      20                 :            :  *
      21                 :            :  *   * Neither the name of the <ORGANIZATION> nor the names of its contributors
      22                 :            :  *     may be used to endorse or promote products derived from this software
      23                 :            :  *     without specific prior written permission.
      24                 :            :  *
      25                 :            :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      26                 :            :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      27                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      28                 :            :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      29                 :            :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      30                 :            :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      31                 :            :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      32                 :            :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      33                 :            :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      34                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      35                 :            :  * POSSIBILITY OF SUCH DAMAGE.
      36                 :            :  */
      37                 :            : /* Copyright (C) 2007,2010 Olly Betts
      38                 :            :  * Copyright (C) 2010 Evgeny Sizikov
      39                 :            :  *
      40                 :            :  * This program is free software; you can redistribute it and/or
      41                 :            :  * modify it under the terms of the GNU General Public License as
      42                 :            :  * published by the Free Software Foundation; either version 2 of the
      43                 :            :  * License, or (at your option) any later version.
      44                 :            :  *
      45                 :            :  * This program is distributed in the hope that it will be useful,
      46                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      47                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      48                 :            :  * GNU General Public License for more details.
      49                 :            :  *
      50                 :            :  * You should have received a copy of the GNU General Public License
      51                 :            :  * along with this program; if not, write to the Free Software
      52                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      53                 :            :  */
      54                 :            : 
      55                 :            : #include <config.h>
      56                 :            : 
      57                 :            : #include "steminternal.h"
      58                 :            : 
      59                 :            : #include <xapian/error.h>
      60                 :            : 
      61                 :            : #include "omassert.h"
      62                 :            : 
      63                 :            : #include <cstdlib>
      64                 :            : #include <cstring>
      65                 :            : 
      66                 :            : #include <string>
      67                 :            : 
      68                 :            : using namespace std;
      69                 :            : 
      70                 :            : #define CREATE_SIZE 16
      71                 :            : 
      72                 :      32951 : extern symbol * create_s() {
      73                 :      32951 :     void * mem = malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol));
      74         [ -  + ]:      32951 :     if (mem == NULL) throw std::bad_alloc();
      75                 :      32951 :     symbol * p = reinterpret_cast<symbol*>(HEAD + static_cast<char *>(mem));
      76                 :      32951 :     SET_CAPACITY(p, CREATE_SIZE);
      77                 :      32951 :     SET_SIZE(p, CREATE_SIZE);
      78                 :      32951 :     return p;
      79                 :            : }
      80                 :            : 
      81                 :            : /*
      82                 :            :    new_c = skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c
      83                 :            :    if n +ve, or n characters backwards from p + c - 1 if n -ve. new_c is the new
      84                 :            :    value of the cursor c, or -1 on failure.
      85                 :            : 
      86                 :            :    -- used to implement hop and next in the utf8 case.
      87                 :            : */
      88                 :            : 
      89                 :  120295619 : extern int skip_utf8(const symbol * p, int c, int lb, int l, int n) {
      90         [ +  + ]:  120295619 :     if (n >= 0) {
      91         [ +  + ]:  239384279 :         for (; n > 0; n--) {
      92         [ +  + ]:  123634517 :             if (c >= l) return -1;
      93         [ +  + ]:  119482879 :             if (p[c++] >= 0xC0) {   /* 1100 0000 */
      94         [ +  + ]:   18023838 :                 while (c < l) {
      95                 :            :                     /* break unless p[c] is 10------ */
      96         [ +  + ]:   17910865 :                     if (p[c] >> 6 != 2) break;
      97                 :    4637104 :                     c++;
      98                 :            :                 }
      99                 :            :             }
     100                 :            :         }
     101                 :            :     } else {
     102         [ +  + ]:     843808 :         for (; n < 0; n++) {
     103         [ +  + ]:     451990 :             if (c <= lb) return -1;
     104         [ +  + ]:     449589 :             if (p[--c] >= 0x80) {   /* 1000 0000 */
     105         [ +  + ]:      32097 :                 while (c > lb) {
     106         [ +  + ]:      32042 :                     if (p[c] >= 0xC0) break; /* 1100 0000 */
     107                 :      18433 :                     c--;
     108                 :            :                 }
     109                 :            :             }
     110                 :            :         }
     111                 :            :     }
     112                 :  120295619 :     return c;
     113                 :            : }
     114                 :            : 
     115                 :            : 
     116                 :            : /* Increase the size of the buffer pointed to by p to at least n symbols.
     117                 :            :  * If insufficient memory, throw std::bad_alloc().
     118                 :            :  */
     119                 :      31772 : static symbol * increase_size(symbol * p, int n) {
     120                 :      31772 :     int new_size = n + 20;
     121                 :            :     void * mem = realloc(reinterpret_cast<char *>(p) - HEAD,
     122                 :      31772 :                          HEAD + (new_size + 1) * sizeof(symbol));
     123         [ -  + ]:      31772 :     if (mem == NULL) {
     124                 :          0 :         throw std::bad_alloc();
     125                 :            :     }
     126                 :      31772 :     symbol * q = reinterpret_cast<symbol*>(HEAD + static_cast<char *>(mem));
     127                 :      31772 :     SET_CAPACITY(q, new_size);
     128                 :      31772 :     return q;
     129                 :            : }
     130                 :            : 
     131                 :            : namespace Xapian {
     132                 :            : 
     133 [ #  # ][ #  # ]:      32944 : StemImplementation::~StemImplementation() { }
                 [ -  + ]
     134                 :            : 
     135                 :      32943 : SnowballStemImplementation::~SnowballStemImplementation()
     136                 :            : {
     137                 :      32943 :     lose_s(p);
     138 [ #  # ][ #  # ]:      32943 : }
                 [ -  + ]
     139                 :            : 
     140                 :            : string
     141                 :    3367955 : SnowballStemImplementation::operator()(const string & word)
     142                 :            : {
     143                 :    3367955 :     const symbol * s = reinterpret_cast<const symbol *>(word.data());
     144                 :    3367955 :     replace_s(0, l, word.size(), s);
     145                 :    3367955 :     c = 0;
     146         [ -  + ]:    3367955 :     if (stem() < 0) {
     147                 :            :         // FIXME: Is there a better choice of exception class?
     148                 :          0 :         throw Xapian::InternalError("stemming exception!");
     149                 :            :     }
     150                 :    3367955 :     return string(reinterpret_cast<const char *>(p), l);
     151                 :            : }
     152                 :            : 
     153                 :            : /* Code for character groupings: utf8 cases */
     154                 :            : 
     155                 :   86449087 : int SnowballStemImplementation::get_utf8(int * slot) {
     156                 :            :     int b0, b1;
     157                 :   86449087 :     int tmp = c;
     158         [ +  + ]:   86449087 :     if (tmp >= l) return 0;
     159                 :   83122780 :     b0 = p[tmp++];
     160 [ +  + ][ +  + ]:   83122780 :     if (b0 < 0xC0 || tmp == l) {   /* 1100 0000 */
     161                 :   74769208 :         * slot = b0; return 1;
     162                 :            :     }
     163                 :    8353572 :     b1 = p[tmp++];
     164 [ +  + ][ +  + ]:    8353572 :     if (b0 < 0xE0 || tmp == l) {   /* 1110 0000 */
     165                 :    4471100 :         * slot = (b0 & 0x1F) << 6 | (b1 & 0x3F); return 2;
     166                 :            :     }
     167                 :   86449087 :     * slot = (b0 & 0xF) << 12 | (b1 & 0x3F) << 6 | (p[tmp] & 0x3F); return 3;
     168                 :            : }
     169                 :            : 
     170                 :   37699600 : int SnowballStemImplementation::get_b_utf8(int * slot) {
     171                 :            :     int b0, b1;
     172                 :   37699600 :     int tmp = c;
     173         [ +  + ]:   37699600 :     if (tmp <= lb) return 0;
     174                 :   37144952 :     b0 = p[--tmp];
     175 [ +  + ][ +  + ]:   37144952 :     if (b0 < 0x80 || tmp == lb) {   /* 1000 0000 */
     176                 :   30340985 :         * slot = b0; return 1;
     177                 :            :     }
     178                 :    6803967 :     b1 = p[--tmp];
     179 [ +  + ][ +  + ]:    6803967 :     if (b1 >= 0xC0 || tmp == lb) {   /* 1100 0000 */
     180                 :    2490015 :         * slot = (b1 & 0x1F) << 6 | (b0 & 0x3F); return 2;
     181                 :            :     }
     182                 :   37699600 :     * slot = (p[tmp] & 0xF) << 12 | (b1 & 0x3F) << 6 | (b0 & 0x3F); return 3;
     183                 :            : }
     184                 :            : 
     185                 :            : int
     186                 :   52801437 : SnowballStemImplementation::in_grouping_U(const unsigned char * s, int min,
     187                 :            :                                           int max, int repeat)
     188                 :            : {
     189         [ +  + ]:    8692410 :     do {
     190                 :            :         int ch;
     191                 :   52801437 :         int w = get_utf8(&ch);
     192         [ +  + ]:   52801437 :         if (!w) return -1;
     193 [ +  + ][ +  + ]:   50462942 :         if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
         [ +  + ][ +  + ]
     194                 :   41770532 :             return w;
     195                 :    8692410 :         c += w;
     196                 :            :     } while (repeat);
     197                 :   51759824 :     return 0;
     198                 :            : }
     199                 :            : 
     200                 :            : int
     201                 :     876375 : SnowballStemImplementation::in_grouping_b_U(const unsigned char * s, int min,
     202                 :            :                                             int max, int repeat)
     203                 :            : {
     204         [ +  + ]:     333134 :     do {
     205                 :            :         int ch;
     206                 :     876375 :         int w = get_b_utf8(&ch);
     207         [ +  + ]:     876375 :         if (!w) return -1;
     208 [ +  + ][ +  + ]:     861126 :         if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
         [ +  + ][ +  + ]
     209                 :     527992 :             return w;
     210                 :     333134 :         c -= w;
     211                 :            :     } while (repeat);
     212                 :     848586 :     return 0;
     213                 :            : }
     214                 :            : 
     215                 :            : int
     216                 :   33647650 : SnowballStemImplementation::out_grouping_U(const unsigned char * s, int min,
     217                 :            :                                            int max, int repeat)
     218                 :            : {
     219         [ +  + ]:   27248927 :     do {
     220                 :            :         int ch;
     221                 :   33647650 :         int w = get_utf8(&ch);
     222         [ +  + ]:   33647650 :         if (!w) return -1;
     223 [ +  + ][ +  + ]:   32659838 :         if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0))
         [ +  + ][ +  + ]
     224                 :    5410911 :             /* FIXME: try adding this so gopast in generated code is simpler: if (repeat == 2) c += w; */ return w;
     225                 :   27248927 :         c += w;
     226                 :            :     } while (repeat);
     227                 :    8401737 :     return 0;
     228                 :            : }
     229                 :            : 
     230                 :            : int
     231                 :   36823225 : SnowballStemImplementation::out_grouping_b_U(const unsigned char * s, int min,
     232                 :            :                                              int max, int repeat)
     233                 :            : {
     234         [ +  + ]:   30863838 :     do {
     235                 :            :         int ch;
     236                 :   36823225 :         int w = get_b_utf8(&ch);
     237         [ +  + ]:   36823225 :         if (!w) return -1;
     238 [ +  + ][ +  + ]:   36283826 :         if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0))
         [ +  + ][ +  + ]
     239                 :    5419988 :             return w;
     240                 :   30863838 :         c -= w;
     241                 :            :     } while (repeat);
     242                 :    7099540 :     return 0;
     243                 :            : }
     244                 :            : 
     245                 :   17852313 : int SnowballStemImplementation::eq_s(int s_size, const symbol * s) {
     246 [ +  + ][ +  + ]:   17852313 :     if (l - c < s_size || memcmp(p + c, s, s_size * sizeof(symbol)) != 0)
     247                 :   17837567 :         return 0;
     248                 :      14746 :     c += s_size;
     249                 :   17852313 :     return 1;
     250                 :            : }
     251                 :            : 
     252                 :    3982151 : int SnowballStemImplementation::eq_s_b(int s_size, const symbol * s) {
     253 [ +  + ][ +  + ]:    3982151 :     if (c - lb < s_size || memcmp(p + c - s_size, s, s_size * sizeof(symbol)) != 0)
     254                 :    3599334 :         return 0;
     255                 :     382817 :     c -= s_size;
     256                 :    3982151 :     return 1;
     257                 :            : }
     258                 :            : 
     259                 :            : int
     260                 :   18294112 : SnowballStemImplementation::find_among(const symbol * pool,
     261                 :            :                                        const struct among * v, int v_size,
     262                 :            :                                        const unsigned char * fnum,
     263                 :            :                                        const among_function * f)
     264                 :            : {
     265                 :   18294112 :     int i = 0;
     266                 :   18294112 :     int j = v_size;
     267                 :            : 
     268                 :   18294112 :     const symbol * q = p + c;
     269                 :   18294112 :     int c_orig = c;
     270                 :            : 
     271                 :   18294112 :     int common_i = 0;
     272                 :   18294112 :     int common_j = 0;
     273                 :            : 
     274                 :   18294112 :     int first_key_inspected = 0;
     275                 :            : 
     276                 :   36793451 :     while (1) {
     277                 :   55087563 :         int k = i + ((j - i) >> 1);
     278                 :   55087563 :         int diff = 0;
     279         [ +  + ]:   55087563 :         int common = common_i < common_j ? common_i : common_j; /* smaller */
     280                 :   55087563 :         const struct among * w = v + k;
     281         [ +  + ]:   56443563 :         for (int x = common; x < w->s_size; x++) {
     282         [ +  + ]:   49947374 :             if (c_orig + common == l) { diff = -1; break; }
     283                 :   49048832 :             diff = q[common] - (pool + w->s)[x];
     284         [ +  + ]:   49048832 :             if (diff != 0) break;
     285                 :    1356000 :             common++;
     286                 :            :         }
     287         [ +  + ]:   55087563 :         if (diff < 0) { j = k; common_j = common; }
     288                 :   29573758 :                  else { i = k; common_i = common; }
     289         [ +  + ]:   55087563 :         if (j - i <= 1) {
     290         [ +  + ]:   24676610 :             if (i > 0) break; /* v->s has been inspected */
     291         [ +  + ]:   12764996 :             if (j == i) break; /* only one item in v */
     292                 :            : 
     293                 :            :             /* - but now we need to go round once more to get
     294                 :            :                v->s inspected. This looks messy, but is actually
     295                 :            :                the optimal approach.  */
     296                 :            : 
     297         [ +  + ]:   12692714 :             if (first_key_inspected) break;
     298                 :    6382498 :             first_key_inspected = 1;
     299                 :            :         }
     300                 :            :     }
     301                 :   29422527 :     while (1) {
     302                 :   29422527 :         const struct among * w = v + i;
     303         [ +  + ]:   29422527 :         if (common_i >= w->s_size) {
     304                 :   17624604 :             c = c_orig + w->s_size;
     305 [ -  + ][ #  # ]:   17624604 :             if (!fnum || !fnum[i]) return w->result;
     306                 :            :             {
     307                 :          0 :                 int res = f[fnum[i] - 1](this);
     308                 :          0 :                 c = c_orig + w->s_size;
     309         [ #  # ]:          0 :                 if (res) return w->result;
     310                 :            :             }
     311                 :            :         }
     312                 :   11797923 :         i = w->substring_i;
     313         [ +  + ]:   11797923 :         if (i < 0) return 0;
     314                 :            :     }
     315                 :            : }
     316                 :            : 
     317                 :            : /* find_among_b is for backwards processing. Same comments apply */
     318                 :            : int
     319                 :    7583640 : SnowballStemImplementation::find_among_b(const symbol * pool,
     320                 :            :                                          const struct among * v, int v_size,
     321                 :            :                                          const unsigned char * fnum,
     322                 :            :                                          const among_function * f)
     323                 :            : {
     324                 :    7583640 :     int i = 0;
     325                 :    7583640 :     int j = v_size;
     326                 :            : 
     327                 :    7583640 :     const symbol * q = p + c - 1;
     328                 :    7583640 :     int c_orig = c;
     329                 :            : 
     330                 :    7583640 :     int common_i = 0;
     331                 :    7583640 :     int common_j = 0;
     332                 :            : 
     333                 :    7583640 :     int first_key_inspected = 0;
     334                 :            : 
     335                 :   22906612 :     while (1) {
     336                 :   30490252 :         int k = i + ((j - i) >> 1);
     337                 :   30490252 :         int diff = 0;
     338         [ +  + ]:   30490252 :         int common = common_i < common_j ? common_i : common_j;
     339                 :   30490252 :         const struct among * w = v + k;
     340         [ +  + ]:   42690405 :         for (int x = w->s_size - 1 - common; x >= 0; x--) {
     341         [ +  + ]:   41404924 :             if (c_orig - common == lb) { diff = -1; break; }
     342                 :   38712036 :             diff = q[- common] - (pool + w->s)[x];
     343         [ +  + ]:   38712036 :             if (diff != 0) break;
     344                 :   12200153 :             common++;
     345                 :            :         }
     346         [ +  + ]:   30490252 :         if (diff < 0) { j = k; common_j = common; }
     347                 :   13110578 :                  else { i = k; common_i = common; }
     348         [ +  + ]:   30490252 :         if (j - i <= 1) {
     349         [ +  + ]:    9932226 :             if (i > 0) break;
     350         [ +  + ]:    4697172 :             if (j == i) break;
     351         [ +  + ]:    3312010 :             if (first_key_inspected) break;
     352                 :    2348586 :             first_key_inspected = 1;
     353                 :            :         }
     354                 :            :     }
     355                 :    8940679 :     while (1) {
     356                 :    8940679 :         const struct among * w = v + i;
     357         [ +  + ]:    8940679 :         if (common_i >= w->s_size) {
     358                 :    1522338 :             c = c_orig - w->s_size;
     359 [ +  + ][ +  + ]:    1522338 :             if (!fnum || !fnum[i]) return w->result;
     360                 :            :             {
     361                 :      38415 :                 int res = f[fnum[i] - 1](this);
     362                 :      38415 :                 c = c_orig - w->s_size;
     363         [ +  + ]:      38415 :                 if (res) return w->result;
     364                 :            :             }
     365                 :            :         }
     366                 :    7422464 :         i = w->substring_i;
     367         [ +  + ]:    7422464 :         if (i < 0) return 0;
     368                 :            :     }
     369                 :            : }
     370                 :            : 
     371                 :            : int
     372                 :    5000850 : SnowballStemImplementation::replace_s(int c_bra, int c_ket, int s_size,
     373                 :            :                                       const symbol * s)
     374                 :            : {
     375                 :            :     int adjustment;
     376                 :            :     int len;
     377                 :            :     Assert(p);
     378                 :    5000850 :     adjustment = s_size - (c_ket - c_bra);
     379                 :    5000850 :     len = SIZE(p);
     380         [ +  + ]:    5000850 :     if (adjustment != 0) {
     381         [ +  + ]:    4291858 :         if (adjustment + len > CAPACITY(p)) {
     382                 :      31771 :             p = increase_size(p, adjustment + len);
     383                 :            :         }
     384                 :            :         memmove(p + c_ket + adjustment,
     385                 :            :                 p + c_ket,
     386                 :    4291858 :                 (len - c_ket) * sizeof(symbol));
     387                 :    4291858 :         SET_SIZE(p, adjustment + len);
     388                 :    4291858 :         l += adjustment;
     389         [ +  + ]:    4291858 :         if (c >= c_ket)
     390                 :      88059 :             c += adjustment;
     391                 :            :         else
     392         [ +  + ]:    4203799 :             if (c > c_bra)
     393                 :      10813 :                 c = c_bra;
     394                 :            :     }
     395         [ +  + ]:    5000850 :     if (s_size != 0) memmove(p + c_bra, s, s_size * sizeof(symbol));
     396                 :    5000850 :     return adjustment;
     397                 :            : }
     398                 :            : 
     399                 :    1805865 : int SnowballStemImplementation::slice_check() {
     400                 :            :     Assert(p);
     401 [ +  - ][ +  - ]:    1805865 :     if (bra < 0 || bra > ket || ket > l) {
                 [ -  + ]
     402                 :            : #if 0
     403                 :            :         fprintf(stderr, "faulty slice operation:\n");
     404                 :            :         debug(z, -1, 0);
     405                 :            : #endif
     406                 :          0 :         return -1;
     407                 :            :     }
     408                 :    1805865 :     return 0;
     409                 :            : }
     410                 :            : 
     411                 :    1614265 : int SnowballStemImplementation::slice_from_s(int s_size, const symbol * s) {
     412         [ -  + ]:    1614265 :     if (slice_check()) return -1;
     413                 :    1614265 :     replace_s(bra, ket, s_size, s);
     414                 :    1614265 :     return 0;
     415                 :            : }
     416                 :            : 
     417                 :            : void
     418                 :      18630 : SnowballStemImplementation::insert_s(int c_bra, int c_ket, int s_size,
     419                 :            :                                      const symbol * s)
     420                 :            : {
     421                 :      18630 :     int adjustment = replace_s(c_bra, c_ket, s_size, s);
     422         [ +  + ]:      18630 :     if (c_bra <= bra) bra += adjustment;
     423         [ +  - ]:      18630 :     if (c_bra <= ket) ket += adjustment;
     424                 :      18630 : }
     425                 :            : 
     426                 :     191600 : symbol * SnowballStemImplementation::slice_to(symbol * v) {
     427         [ -  + ]:     191600 :     if (slice_check()) return NULL;
     428                 :            :     {
     429                 :     191600 :         int len = ket - bra;
     430         [ +  + ]:     191600 :         if (CAPACITY(v) < len) {
     431                 :          1 :             v = increase_size(v, len);
     432                 :            :         }
     433                 :     191600 :         memmove(v, p + bra, len * sizeof(symbol));
     434                 :     191600 :         SET_SIZE(v, len);
     435                 :            :     }
     436                 :     191600 :     return v;
     437                 :            : }
     438                 :            : 
     439                 :          0 : symbol * SnowballStemImplementation::assign_to(symbol * v) {
     440                 :          0 :     int len = l;
     441         [ #  # ]:          0 :     if (CAPACITY(v) < len) {
     442                 :          0 :         v = increase_size(v, len);
     443                 :            :     }
     444                 :          0 :     memmove(v, p, len * sizeof(symbol));
     445                 :          0 :     SET_SIZE(v, len);
     446                 :          0 :     return v;
     447                 :            : }
     448                 :            : 
     449                 :            : #if 0
     450                 :            : void SnowballStemImplementation::debug(int number, int line_count) {
     451                 :            :     int i;
     452                 :            :     int limit = SIZE(p);
     453                 :            :     /*if (number >= 0) printf("%3d (line %4d): '", number, line_count);*/
     454                 :            :     if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit);
     455                 :            :     for (i = 0; i <= limit; i++) {
     456                 :            :         if (lb == i) printf("{");
     457                 :            :         if (bra == i) printf("[");
     458                 :            :         if (c == i) printf("|");
     459                 :            :         if (ket == i) printf("]");
     460                 :            :         if (l == i) printf("}");
     461                 :            :         if (i < limit)
     462                 :            :         {   int ch = p[i];
     463                 :            :             if (ch == 0) ch = '#';
     464                 :            :             printf("%c", ch);
     465                 :            :         }
     466                 :            :     }
     467                 :            :     printf("'\n");
     468                 :            : }
     469                 :            : #endif
     470                 :            : }

Generated by: LCOV version 1.8