Ticket #230: search-xapian-generate-errors.04.patch

File search-xapian-generate-errors.04.patch, 29.2 KB (added by Andreas Marienborg, 16 years ago)

Second stab

  • XS/BM25Weight.xs

    === XS/BM25Weight.xs
    ==================================================================
     
    55BM25Weight *
    66new1()
    77    CODE:
     8    try {
    89        RETVAL = new BM25Weight();
     10    } catch (...) {
     11        handleException();
     12    }
    913    OUTPUT:
    1014        RETVAL
    1115
     
    1721    double      b
    1822    double      min_normlen
    1923    CODE:
    20         RETVAL = new BM25Weight(k1, k2, k3, b, min_normlen);
     24    try {
     25        RETVAL = new BM25Weight(k1, k2, k3, b, min_normlen);
     26    } catch (...) {
     27        handleException();
     28    }
    2129    OUTPUT:
    2230        RETVAL
    2331
  • XS/BoolWeight.xs

    === XS/BoolWeight.xs
    ==================================================================
     
    55BoolWeight *
    66new1()
    77    CODE:
    8         RETVAL = new BoolWeight();
     8    try {
     9            RETVAL = new BoolWeight();
     10    } catch (...) {
     11        handleException();
     12    }
    913    OUTPUT:
    1014        RETVAL
    1115
  • XS/Database.xs

    === XS/Database.xs
    ==================================================================
     
    66new1(file)
    77    string      file
    88    CODE:
    9         try {
     9    try {
    1010            RETVAL = new Database(file);
    11         }
    12         catch (const Error &error) {
    13             croak( "Exception: %s", error.get_msg().c_str() );
    14         }
     11    } catch (...) {
     12        handleException();
     13    }
    1514    OUTPUT:
    1615        RETVAL
    1716
     
    1918new2(database)
    2019    Database *  database
    2120    CODE:
    22         try {
     21    try {
    2322            RETVAL = new Database(*database);
    24         }
    25         catch (const Error &error) {
    26             croak( "Exception: %s", error.get_msg().c_str() );
    27         }
     23    } catch (...) {
     24        handleException();
     25    }
    2826    OUTPUT:
    2927        RETVAL
    3028
     
    3230Database::add_database(database)
    3331    Database *  database
    3432    CODE:
    35         try {
     33    try {
    3634            THIS->add_database(*database);
    37         }
    38         catch (const Error &error) {
    39             croak( "Exception: %s", error.get_msg().c_str() );
    40         }
     35    } catch (...) {
     36        handleException();
     37    }
    4138
    4239void
    4340Database::reopen()
    4441    CODE:
    45         try {
    46             THIS->reopen();
    47         }
    48         catch (const Error &error) {
    49             croak( "Exception: %s", error.get_msg().c_str() );
    50         }
     42    try {
     43        THIS->reopen();
     44    } catch (...) {
     45        handleException();
     46    }
    5147
    5248string
    5349Database::get_description()
    5450    CODE:
    55         try {
    56             RETVAL = THIS->get_description();
    57         }
    58         catch (const Error &error) {
    59             croak( "Exception: %s", error.get_msg().c_str() );
    60         }
     51    try {
     52        RETVAL = THIS->get_description();
     53    } catch (...) {
     54        handleException();
     55    }
    6156    OUTPUT:
    6257        RETVAL
    6358
     
    6560Database::termlist_begin(did)
    6661    docid       did
    6762    CODE:
    68         try {
     63    try {
    6964            RETVAL = new TermIterator(THIS->termlist_begin(did));
    70         }
    71         catch (const Error &error) {
    72             croak( "Exception: %s", error.get_msg().c_str() );
    73         }
     65    } catch (...) {
     66        handleException();
     67    }
    7468    OUTPUT:
    7569        RETVAL
    7670
     
    7872Database::termlist_end(did)
    7973    docid       did
    8074    CODE:
    81         try {
     75    try {
    8276            RETVAL = new TermIterator(THIS->termlist_end(did));
    83         }
    84         catch (const Error &error) {
    85             croak( "Exception: %s", error.get_msg().c_str() );
    86         }
     77    } catch (...) {
     78        handleException();
     79    }
    8780    OUTPUT:
    8881        RETVAL
    8982
     
    9285    docid       did
    9386    string      term
    9487    CODE:
    95         try {
     88    try {
    9689            RETVAL = new PositionIterator(THIS->positionlist_begin(did, term));
    97         }
    98         catch (const Error &error) {
    99             croak( "Exception: %s", error.get_msg().c_str() );
    100         }
     90    } catch (...) {
     91        handleException();
     92    }
    10193    OUTPUT:
    10294        RETVAL
    10395
     
    10698    docid       did
    10799    string      term
    108100    CODE:
    109         try {
     101    try {
    110102            RETVAL = new PositionIterator(THIS->positionlist_end(did, term));
    111         }
    112         catch (const Error &error) {
    113             croak( "Exception: %s", error.get_msg().c_str() );
    114         }
     103    } catch (...) {
     104        handleException();
     105    }
    115106    OUTPUT:
    116107        RETVAL
    117108
     
    119110Database::allterms_begin(prefix = "")
    120111    string prefix
    121112    CODE:
    122         try {
     113    try {
    123114            RETVAL = new TermIterator(THIS->allterms_begin(prefix));
    124         }
    125         catch (const Error &error) {
    126             croak( "Exception: %s", error.get_msg().c_str() );
    127         }
     115    } catch (...) {
     116        handleException();
     117    }
    128118    OUTPUT:
    129119        RETVAL
    130120
     
    132122Database::allterms_end(prefix = "")
    133123    string prefix
    134124    CODE:
    135         try {
     125    try {
    136126            RETVAL = new TermIterator(THIS->allterms_end(prefix));
    137         }
    138         catch (const Error &error) {
    139             croak( "Exception: %s", error.get_msg().c_str() );
    140         }
     127    } catch (...) {
     128        handleException();
     129    }
    141130    OUTPUT:
    142131        RETVAL
    143132
     
    145134Database::postlist_begin(term)
    146135    string      term
    147136    CODE:
    148         try {
     137    try {
    149138            RETVAL = new PostingIterator(THIS->postlist_begin(term));
    150         }
    151         catch (const Error &error) {
    152             croak( "Exception: %s", error.get_msg().c_str() );
    153         }
     139    } catch (...) {
     140        handleException();
     141    }
    154142    OUTPUT:
    155143        RETVAL
    156144
     
    158146Database::postlist_end(term)
    159147    string      term
    160148    CODE:
    161         try {
     149    try {
    162150            RETVAL = new PostingIterator(THIS->postlist_end(term));
    163         }
    164         catch (const Error &error) {
    165             croak( "Exception: %s", error.get_msg().c_str() );
    166         }
     151    } catch (...) {
     152        handleException();
     153    }
    167154    OUTPUT:
    168155        RETVAL
    169156
    170157doccount
    171158Database::get_doccount()
    172159    CODE:
    173         try {
    174             RETVAL = THIS->get_doccount();
    175         }
    176         catch (const Error &error) {
    177             croak( "Exception: %s", error.get_msg().c_str() );
    178         }
     160    try {
     161        RETVAL = THIS->get_doccount();
     162    } catch (...) {
     163        handleException();
     164    }
    179165    OUTPUT:
    180166        RETVAL
    181167
    182168docid
    183169Database::get_lastdocid()
    184170    CODE:
    185         try {
    186             RETVAL = THIS->get_lastdocid();
    187         }
    188         catch (const Error &error) {
    189             croak( "Exception: %s", error.get_msg().c_str() );
    190         }
     171    try {
     172        RETVAL = THIS->get_lastdocid();
     173    } catch (...) {
     174        handleException();
     175    }
    191176    OUTPUT:
    192177        RETVAL
    193178
    194179doclength
    195180Database::get_avlength()
    196181    CODE:
    197         try {
    198             RETVAL = THIS->get_avlength();
    199         }
    200         catch (const Error &error) {
    201             croak( "Exception: %s", error.get_msg().c_str() );
    202         }
     182    try {
     183        RETVAL = THIS->get_avlength();
     184    } catch (...) {
     185        handleException();
     186    }
    203187    OUTPUT:
    204188        RETVAL
    205189
     
    207191Database::get_termfreq(tname)
    208192    string      tname
    209193    CODE:
    210         try {
    211             RETVAL = THIS->get_termfreq(tname);
    212         }
    213         catch (const Error &error) {
    214             croak( "Exception: %s", error.get_msg().c_str() );
    215         }
     194    try {
     195        RETVAL = THIS->get_termfreq(tname);
     196    } catch (...) {
     197        handleException();
     198    }
    216199    OUTPUT:
    217200        RETVAL
    218201
     
    220203Database::term_exists(tname)
    221204    string      tname
    222205    CODE:
    223         try {
     206    try {
    224207            RETVAL = THIS->term_exists(tname);
    225         }
    226         catch (const Error &error) {
    227             croak( "Exception: %s", error.get_msg().c_str() );
    228         }
     208    } catch (...) {
     209        handleException();
     210    }
    229211    OUTPUT:
    230212        RETVAL
    231213
     
    233215Database::get_collection_freq(tname)
    234216    string      tname
    235217    CODE:
    236         try {
     218    try {
    237219            RETVAL = THIS->get_collection_freq(tname);
    238         }
    239         catch (const Error &error) {
    240             croak( "Exception: %s", error.get_msg().c_str() );
    241         }
     220    } catch (...) {
     221        handleException();
     222    }
    242223    OUTPUT:
    243224        RETVAL
    244225
     
    246227Database::get_doclength(did)
    247228    docid       did
    248229    CODE:
    249         try {
     230    try {
    250231            RETVAL = THIS->get_doclength(did);
    251         }
    252         catch (const Error &error) {
    253             croak( "Exception: %s", error.get_msg().c_str() );
    254         }
     232    } catch (...) {
     233        handleException();
     234    }
    255235    OUTPUT:
    256236        RETVAL
    257237
    258238void
    259239Database::keep_alive()
    260240    CODE:
    261         try {
     241    try {
    262242            THIS->keep_alive();
    263         }
    264         catch (const Error &error) {
    265             croak( "Exception: %s", error.get_msg().c_str() );
    266         }
     243    } catch (...) {
     244        handleException();
     245    }
    267246
    268247Document *
    269248Database::get_document(docid did)
    270249    CODE:
    271         try {
     250    try {
    272251            RETVAL = new Document(THIS->get_document(did));
    273         }
    274         catch (const Error &error) {
    275             croak( "Exception: %s", error.get_msg().c_str() );
    276         }
     252    } catch (...) {
     253        handleException();
     254    }
    277255    OUTPUT:
    278256        RETVAL
    279257
  • XS/Enquire.xs

    === XS/Enquire.xs
    ==================================================================
     
    66Enquire::new(databases)
    77    Database *  databases
    88    CODE:
     9    try {
    910        RETVAL = new Enquire(*databases);
     11    } catch (...) {
     12        handleException();
     13    }
    1014    OUTPUT:
    1115        RETVAL
    1216
     
    1418Enquire::set_query1(query)
    1519    Query *     query
    1620    CODE:
    17         THIS->set_query(*query);
     21    try {
     22            THIS->set_query(*query);
     23    } catch (...) {
     24        handleException();
     25    }
    1826
    1927void
    2028Enquire::set_query2(query, len)
    2129    Query *     query
    2230    termcount   len
    2331    CODE:
    24         THIS->set_query(*query, len);
     32    try {
     33            THIS->set_query(*query, len);
     34    } catch (...) {
     35        handleException();
     36    }
    2537
    2638Query *
    2739Enquire::get_query();
    2840    CODE:
     41    try {
    2942        RETVAL = new Query(THIS->get_query());
     43    } catch (...) {
     44        handleException();
     45    }
    3046    OUTPUT:
    3147        RETVAL
    3248
     
    3450Enquire::set_collapse_key(collapse_key)
    3551    valueno     collapse_key
    3652    CODE:
     53    try {
    3754        THIS->set_collapse_key(collapse_key);
    38 
     55    } catch (...) {
     56        handleException();
     57    }
     58       
    3959void
    4060Enquire::set_docid_order(order)
    4161    int         order
    4262    CODE:
     63    try {
    4364        THIS->set_docid_order(static_cast<Enquire::docid_order>(order));
    44 
     65    } catch (...) {
     66        handleException();
     67    }
     68       
    4569void
    4670Enquire::set_cutoff(percent_cutoff, weight_cutoff = NO_INIT)
    4771    percent     percent_cutoff
    4872    weight      weight_cutoff
    4973    CODE:
     74    try {
    5075        if (items == 3) { /* items includes the hidden this pointer */
    5176            THIS->set_cutoff(percent_cutoff, weight_cutoff);
    5277        } else {
    5378            THIS->set_cutoff(percent_cutoff);
    5479        }
    55 
     80    } catch (...) {
     81        handleException();
     82    }
     83       
    5684void
    5785Enquire::set_sort_by_relevance()
    5886
     
    6189    valueno     sort_key
    6290    bool        ascending
    6391    CODE:
    64         if (items == 3) { /* items includes the hidden this pointer */
    65             THIS->set_sort_by_value(sort_key, ascending);
    66         } else {
    67             THIS->set_sort_by_value(sort_key);
    68         }
    69 
     92    try {
     93        if (items == 3) { /* items includes the hidden this pointer */
     94            THIS->set_sort_by_value(sort_key, ascending);
     95        } else {
     96            THIS->set_sort_by_value(sort_key);
     97        }
     98    } catch (...) {
     99        handleException();
     100    }
     101       
    70102void
    71103Enquire::set_sort_by_value_then_relevance(sort_key, ascending = NO_INIT)
    72104    valueno     sort_key
    73105    bool        ascending
    74106    CODE:
    75         if (items == 3) { /* items includes the hidden this pointer */
    76             THIS->set_sort_by_value_then_relevance(sort_key, ascending);
    77         } else {
    78             THIS->set_sort_by_value_then_relevance(sort_key);
    79         }
     107    try {
     108        if (items == 3) { /* items includes the hidden this pointer */
     109            THIS->set_sort_by_value_then_relevance(sort_key, ascending);
     110        } else {
     111            THIS->set_sort_by_value_then_relevance(sort_key);
     112        }
     113    } catch (...) {
     114        handleException();
     115    }
    80116
    81117void
    82118Enquire::set_sort_by_relevance_then_value(sort_key, ascending = NO_INIT)
    83119    valueno     sort_key
    84120    bool        ascending
    85121    CODE:
    86         if (items == 3) { /* items includes the hidden this pointer */
    87             THIS->set_sort_by_relevance_then_value(sort_key, ascending);
    88         } else {
    89             THIS->set_sort_by_relevance_then_value(sort_key);
    90         }
     122    try {
     123        if (items == 3) { /* items includes the hidden this pointer */
     124            THIS->set_sort_by_relevance_then_value(sort_key, ascending);
     125        } else {
     126            THIS->set_sort_by_relevance_then_value(sort_key);
     127        }
     128    } catch (...) {
     129        handleException();
     130    }
    91131
    92132void
    93133Enquire::set_sort_by_key(sorter, ascending = NO_INIT)
    94134    MultiValueSorter * sorter
    95135    bool        ascending
    96136    CODE:
    97         // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
    98         // a SEGV!
    99         SvREFCNT_inc(ST(1));
    100         if (items == 3) { /* items includes the hidden this pointer */
    101             THIS->set_sort_by_key(sorter, ascending);
    102         } else {
    103             THIS->set_sort_by_key(sorter);
    104         }
     137    try {
     138        // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
     139        // a SEGV!
     140        SvREFCNT_inc(ST(1));
     141        if (items == 3) { /* items includes the hidden this pointer */
     142            THIS->set_sort_by_key(sorter, ascending);
     143        } else {
     144            THIS->set_sort_by_key(sorter);
     145        }
     146    } catch (...) {
     147        handleException();
     148    }
     149       
    105150
    106151void
    107152Enquire::set_sort_by_key_then_relevance(sorter, ascending = NO_INIT)
    108153    MultiValueSorter * sorter
    109154    bool        ascending
    110155    CODE:
    111         // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
    112         // a SEGV!
    113         SvREFCNT_inc(ST(1));
    114         if (items == 3) { /* items includes the hidden this pointer */
    115             THIS->set_sort_by_key_then_relevance(sorter, ascending);
    116         } else {
    117             THIS->set_sort_by_key_then_relevance(sorter);
    118         }
     156    try {
     157        // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
     158        // a SEGV!
     159        SvREFCNT_inc(ST(1));
     160        if (items == 3) { /* items includes the hidden this pointer */
     161            THIS->set_sort_by_key_then_relevance(sorter, ascending);
     162        } else {
     163            THIS->set_sort_by_key_then_relevance(sorter);
     164        }
     165    } catch (...) {
     166        handleException();
     167    }
    119168
    120169void
    121170Enquire::set_sort_by_relevance_then_key(sorter, ascending = NO_INIT)
    122171    MultiValueSorter * sorter
    123172    bool        ascending
    124173    CODE:
    125         // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
    126         // a SEGV!
    127         SvREFCNT_inc(ST(1));
    128         if (items == 3) { /* items includes the hidden this pointer */
    129             THIS->set_sort_by_relevance_then_key(sorter, ascending);
    130         } else {
    131             THIS->set_sort_by_relevance_then_key(sorter);
    132         }
     174    try {
     175        // FIXME: no corresponding SvREFCNT_dec(), but a leak seems better than
     176        // a SEGV!
     177        SvREFCNT_inc(ST(1));
     178        if (items == 3) { /* items includes the hidden this pointer */
     179            THIS->set_sort_by_relevance_then_key(sorter, ascending);
     180        } else {
     181            THIS->set_sort_by_relevance_then_key(sorter);
     182        }
     183    } catch (...) {
     184        handleException();
     185    }
     186       
    133187
    134188MSet *
    135189Enquire::get_mset1(first, maxitems, checkatleast = NO_INIT, rset = NO_INIT, func = NO_INIT)
     
    139193    RSet *      rset
    140194    SV *        func
    141195    CODE:
    142         MSet mset;
    143         switch (items) { /* items includes the hidden this pointer */
    144             case 3:
    145                 mset = THIS->get_mset(first, maxitems);
    146                 break;
    147             case 4:
    148                 mset = THIS->get_mset(first, maxitems, checkatleast);
    149                 break;
    150             case 5:
    151                 mset = THIS->get_mset(first, maxitems, checkatleast, rset);
    152                 break;
    153             case 6: {
    154                 perlMatchDecider d = perlMatchDecider(func);
    155                 mset = THIS->get_mset(first, maxitems, checkatleast, rset, &d);
    156                 break;
    157             }
    158             default:
    159                 croak("Bad parameter count for get_mset1");
    160         }
    161         RETVAL = new MSet(mset);
     196    try {
     197            MSet mset;
     198        switch (items) { /* items includes the hidden this pointer */
     199            case 3: {
     200                    mset = THIS->get_mset(first, maxitems);
     201                        break;
     202            }
     203            case 4: {
     204                    mset = THIS->get_mset(first, maxitems, checkatleast);               
     205                        break;
     206            }
     207            case 5: {
     208                    mset = THIS->get_mset(first, maxitems, checkatleast, rset);
     209                    break;
     210            }
     211            case 6: {
     212                    perlMatchDecider d = perlMatchDecider(func);
     213                        mset = THIS->get_mset(first, maxitems, checkatleast, rset, &d);   
     214                    break;
     215            }
     216            default:
     217                croak("Bad parameter count for get_mset1");
     218        }
     219        RETVAL = new MSet(mset);
     220    } catch (...) {
     221        handleException();
     222    }   
    162223    OUTPUT:
    163224        RETVAL
    164225
     
    168229    doccount    maxitems
    169230    SV *        func
    170231    CODE:
    171         perlMatchDecider d = perlMatchDecider(func);
    172         RETVAL = new MSet(THIS->get_mset(first, maxitems, 0, NULL, &d));
     232    try {
     233        perlMatchDecider d = perlMatchDecider(func);
     234        RETVAL = new MSet(THIS->get_mset(first, maxitems, 0, NULL, &d));       
     235    } catch (...) {
     236        handleException();
     237    }
    173238    OUTPUT:
    174239        RETVAL
    175240
     
    178243    doccount    maxitems
    179244    RSet *      rset
    180245    CODE:
     246    try {       
    181247        RETVAL = new ESet(THIS->get_eset(maxitems, *rset));
     248    } catch (...) {
     249        handleException();
     250    }
    182251    OUTPUT:
    183252        RETVAL
    184253
    185254TermIterator *
    186255Enquire::get_matching_terms_begin1(docid did)
    187256    CODE:
     257    try {
    188258        RETVAL = new TermIterator(THIS->get_matching_terms_begin(did));
     259    } catch (...) {
     260        handleException();
     261    }
    189262    OUTPUT:
    190263        RETVAL
    191264
    192265TermIterator *
    193266Enquire::get_matching_terms_begin2(it)
    194         MSetIterator *        it
     267    MSetIterator *        it
    195268    CODE:
     269    try {
    196270        RETVAL = new TermIterator(THIS->get_matching_terms_begin(* it));
     271    } catch (...) {
     272        handleException();
     273    }
    197274    OUTPUT:
    198275        RETVAL
    199276
    200277TermIterator *
    201278Enquire::get_matching_terms_end1(docid did)
    202279    CODE:
     280    try {
    203281        RETVAL = new TermIterator(THIS->get_matching_terms_end(did));
     282    } catch (...) {
     283        handleException();
     284    }
    204285    OUTPUT:
    205286        RETVAL
    206287
    207288TermIterator *
    208289Enquire::get_matching_terms_end2(it)
    209         MSetIterator *  it
     290    MSetIterator *  it
    210291    CODE:
     292    try {
    211293        RETVAL = new TermIterator(THIS->get_matching_terms_end(* it));
     294    } catch (...) {
     295        handleException();
     296    }
    212297    OUTPUT:
    213298        RETVAL
    214299
     
    216301Enquire::set_weighting_scheme(weight_)
    217302        Weight *  weight_
    218303    CODE:
    219         THIS->set_weighting_scheme(*weight_);
     304    try {
     305            THIS->set_weighting_scheme(*weight_);
     306    } catch (...) {
     307        handleException();
     308    }
    220309
    221310
    222311string
  • Xapian.pm

    === Xapian.pm
    ==================================================================
     
    1212use Search::Xapian::Document;
    1313use Search::Xapian::ESet;
    1414use Search::Xapian::ESetIterator;
     15use Search::Xapian::Error;
    1516use Search::Xapian::MSet;
    1617use Search::Xapian::MSetIterator;
    1718use Search::Xapian::MultiValueSorter;
  • Xapian.xs

    === Xapian.xs
    ==================================================================
     
    1313#ifdef __cplusplus
    1414}
    1515#endif
     16#undef get_context
    1617
    1718using namespace std;
    1819using namespace Xapian;
    1920
     21#include "handleException.c"
     22
    2023/* PerlStopper class
    2124 *
    2225 * Make operator() call Perl $OBJECT->stop_word
     
    121124INCLUDE: XS/MSet.xs
    122125INCLUDE: XS/MSetIterator.xs
    123126INCLUDE: XS/ESet.xs
     127INCLUDE: XS/Error.xs
    124128INCLUDE: XS/ESetIterator.xs
    125129INCLUDE: XS/RSet.xs
    126130INCLUDE: XS/MultiValueSorter.xs
  • t/databasemodified.t

    === t/databasemodified.t
    ==================================================================
     
     1# Before `make install' is performed this script should be runnable with
     2# `make test'. After `make install' it should work as `perl test.pl'
     3
     4#########################
     5
     6# change 'tests => 1' to 'tests => last_test_to_print';
     7
     8use Test;
     9use Devel::Peek;
     10BEGIN { plan tests => 5 };
     11use Search::Xapian qw(:standard);
     12ok(1); # If we made it this far, we're ok.
     13
     14#########################
     15
     16# Insert your test code below, the Test module is use()ed here so read
     17# its man page ( perldoc Test ) for help writing this test script.
     18
     19# first create database dir, if it doesn't exist;
     20my $db_dir = 'testdb-exception-modified';
     21
     22if( (! -e $db_dir) or (! -d $db_dir) ) {
     23  mkdir( $db_dir );
     24}
     25
     26opendir( DB_DIR, $db_dir );
     27while( defined( my $file = readdir( DB_DIR ) ) ) {
     28  next if $file =~ /^\.+$/;
     29  unlink( "$db_dir/$file" ) or die "Could not delete '$db_dir/$file': $!";
     30}
     31closedir( DB_DIR );
     32
     33my $create = Search::Xapian::WritableDatabase->new( $db_dir, [Search::Xapian::DB_CREATE, 4096]);
     34
     35$create = undef;
     36
     37my $read = Search::Xapian::Database->new( $db_dir );
     38
     39my $write = Search::Xapian::WritableDatabase->new( $db_dir, Search::Xapian::DB_CREATE_OR_OPEN );
     40
     41
     42
     43my $enq = $read->enquire(OP_OR, "test");
     44
     45# lets try to index something
     46my $term = 'test';
     47
     48my $docid;
     49for my $num (1..1000) {
     50      my $doc = Search::Xapian::Document->new();
     51
     52    $doc->set_data( "$term $num" );
     53
     54    $doc->add_posting( $term, 0 );
     55    $doc->add_posting( $num, 1 );
     56
     57    $doc->add_value(0, $num);
     58    $write->add_document( $doc );
     59   
     60}
     61$write->flush();
     62$read->reopen();
     63
     64for my $num qw (three four five) {
     65    my $doc = Search::Xapian::Document->new();
     66
     67  $doc->set_data( "$term $num" );
     68
     69  $doc->add_posting( $term, 0 );
     70  $doc->add_posting( $num, 1 );
     71
     72  $doc->add_value(0, $num);
     73  $write->add_document( $doc );
     74  $write->flush();
     75}
     76$write->flush();
     77#$read->reopen();
     78#yay
     79eval {
     80    my $mset = $enq->get_mset(0, 10);   
     81};
     82ok($@);
     83ok(ref($@), "Search::Xapian::DatabaseModifiedError", "correct class for exception");
     84ok(UNIVERSAL::isa($@, 'Search::Xapian::Error'));
     85
     86ok($@->get_msg, "The revision being read has been discarded - you should call Xapian::Database::reopen() and retry the operation", "get_msg works");
     87
     881;
  • generate_exception_modules.pl

    === generate_exception_modules.pl
    ==================================================================
     
     1#!/usr/bin/perl
     2
     3# Author: Andreas Marienborg <andreas.marienborg@gmail.com>
     4# Donated as is to xapian project. Use and modify as see fit
     5
     6use strict;
     7use warnings;
     8
     9use Template;
     10
     11BEGIN {
     12    my $l = shift;
     13    if (!defined($l) or $l eq '') {
     14        die <<END;
     15First parameter should be directory where 'exception_data.pm' can be found
     16It will be added to INC for this session.
     17END
     18    }
     19    push(@INC, $l);
     20
     21}
     22# We could default to ".", as that is the most logical, but I prefer a
     23# propper "Yes, I do want to create it here, since it modifies some files"
     24
     25my $path = shift or die "No second parameter (output-path) specified";
     26
     27mkdir($path) unless -d $path;
     28mkdir("$path/Xapian") unless -d "$path/Xapian";
     29mkdir("$path/XS") unless -d "$path/XS";
     30
     31# We load the exception data from xapian-core.
     32use exception_data qw(@baseclasses @classes);
     33
     34my $classes = parse_classes(@baseclasses, @classes);
     35my $templates = read_templates();
     36
     37# create a template-toolkit object that we use troughout
     38my $tt = Template->new();
     39#die dump($templates);
     40
     41# render is recursive, rendering all children on the class etc
     42render($tt, $classes->{'Error'});
     43
     44
     45# fix typemap
     46open(my $TM, "<", "typemap") or die "cannot read 'typemap': $!";
     47my @tm = <$TM>;
     48close($TM);
     49
     50
     51# Need to find the position of the Error definitions. Any missing
     52# exception-classes will be added after that.
     53# Since typemap is a "dumb" file, we modify it in place
     54
     55my $pos = 0;
     56foreach (@tm) {
     57    $pos++;
     58    last if (/^Error \*/);
     59}
     60foreach my $cls (keys %$classes) {
     61    $cls = $cls;
     62   
     63    warn "checking for $cls\n";
     64    if (!grep { /^$cls/} @tm) {
     65        warn "   not found, inserting at $pos\n";
     66        splice(@tm, $pos++, 0, "$cls\tO_OBJECT\n");
     67        splice(@tm, $pos++, 0, "$cls *\tO_OBJECT\n");
     68       
     69    }
     70}
     71# truncate and output
     72open($TM, ">", "typemap") or die "cannot write 'typemap': $!";
     73print $TM join("", @tm);
     74close $TM;
     75
     76# The exception catching in C needs to be properly sorted
     77# with the rightmost class first (the ones without children)
     78# order_children creates a flat tree
     79my $ordered_classes = order_children($classes->{'Error'});
     80
     81# write new handleException.h
     82{
     83    my $t = $templates->{'handleException'};
     84    $tt->process(\$t, {
     85        'classes' => $ordered_classes
     86    }, "handleException.c") || die $tt->error;
     87}
     88# done!;
     89exit(0);
     90
     91sub render {
     92    my $tt = shift;
     93    my $class = shift;
     94    return unless $class->{class};
     95    warn "rendering " . $class->{class};
     96    my $t = $class->{class} eq 'Error' ? $templates->{'Error.pm'} : $templates->{'Children.pm'};
     97    my $xs_t = $templates->{'Error.xs'};
     98    $tt->process(\$t, {
     99        'class' => $class
     100    }, "$path/Xapian/" . $class->{class} . ".pm") || die $tt->error;
     101    $tt->process(\$xs_t, {
     102        'class' => $class
     103    }, "$path/XS/" . $class->{class} . ".xs") || die $tt->error;
     104    foreach my $child (@{$class->{children}}) {
     105        render($tt, $child);
     106    }
     107   
     108}
     109
     110# returns an ordered list of decreasing catch-priority
     111
     112sub order_children {
     113    my $class = shift;
     114    my @o;
     115    if ($class->{children}) {
     116        foreach (@{ $class->{children}}) {
     117            push(@o, order_children($_));
     118        }
     119    }
     120    push @o, $class;
     121    return wantarray ? @o : \@o;
     122}
     123
     124# parses trough the classes found and builds a hash-structure of it
     125
     126sub parse_classes {
     127    my $classes = {
     128        'Error' => {
     129            'class' => 'Error',
     130        }
     131    };
     132    foreach (@_) {
     133        my ($cls, $parent, $description) = split /\t/;
     134        print $cls . " - " . $parent . "\n";
     135        $description =~ s!^(/| )\*(\*|/|)!!mg;
     136        $description =~ s!\*/$!!mg;
     137        my ($head, $desc) = split('\n\n', $description, 2) if ($description =~ m/\n\n/);
     138
     139        #only one line of description
     140        $head = $description if (!$head);
     141        my $class = {
     142            'class' => $cls,
     143            'parent' => $parent,
     144            'orig_desc' => $description,
     145            'header' => $head,
     146            'description' => $desc
     147        };
     148        push(@{ $classes->{$parent}->{children}}, $class);
     149        $classes->{$cls} = $class;
     150    }
     151    return $classes;
     152   
     153}
     154
     155# this reads trough our templates in __DATA__ and parses it into
     156# different sections
     157
     158sub read_templates {
     159    my $templates = {};
     160    my $templ = '';
     161    my @t;
     162    while (<DATA>) {
     163        next if (/^\s*$/) && !$templ;
     164        if (/^# TMPL (.*)/) {
     165            # new template found
     166            if ($templ) {
     167                # save old template
     168                $templates->{$templ} = join('', @t);
     169                @t = ();
     170            }
     171            $templ = $1;
     172        } else {
     173            push(@t, $_);
     174#            print "$templ : $_";
     175        }
     176       
     177    }
     178    $templates->{$templ} = join('', @t);
     179    return $templates;
     180}
     1811;
     182
     183__DATA__
     184
     185# TMPL Error.pm
     186package Search::Xapian::Error;
     187
     188=head1 NAME
     189
     190Search::Xapian::[% class.class %] - Base-class for all exceptions in Search::Xapian
     191
     192=head1 DESCRIPTION
     193
     194This class is an abstract class in C++, it cannot be instanated itself. In perl there
     195is no such concept, but you should not need to create instances of theese objects
     196yourself.
     197
     198=head1 METHODS
     199
     200All exception-objects has the following methods
     201
     202=head2 get_msg
     203
     204Returns a string with a descriptive error message, useful for outputing
     205
     206=head2 get_type
     207
     208The type of this error (e.g. "DocNotFoundError".).
     209
     210=head2 get_context
     211
     212Optional context information, returned as a string
     213
     214=head2 get_errno
     215
     216Returns the errno for this error (optional)
     217
     218=cut
     219
     220use 5.006;
     221use strict;
     222use warnings;
     223use Carp;
     224
     225require DynaLoader;
     226
     227[% FOR cls IN class.children -%]
     228use Search::Xapian::[% cls.class %];
     229[% END %]
     230our @ISA = qw(DynaLoader);
     231
     232# Preloaded methods go here.
     233
     234# In a new thread, copy objects of this class to unblessed, undef values.
     235sub CLONE_SKIP { 1 }
     236
     237sub new {
     238    my $class = shift;
     239    my ($self);
     240    bless $self, $class;
     241
     242    return $self;
     243}
     244
     2451;
     246
     247
     248# TMPL Error.xs
     249MODULE = Search::Xapian                 PACKAGE = Search::Xapian::[% class.class %]
     250
     251PROTOTYPES: ENABLE
     252
     253string
     254[% class.class %]::get_type()
     255
     256string
     257[% class.class %]::get_msg()
     258
     259string
     260[% class.class %]::get_context()
     261
     262int
     263[% class.class %]::get_errno()
     264
     265void
     266[% class.class %]::DESTROY()
     267
     268[% FOR cls IN class.children -%]
     269INCLUDE: XS/[% cls.class %].xs
     270[% END %]
     271
     272# TMPL Children.pm
     273package Search::Xapian::[% class.class %];
     274
     275=head1 NAME
     276
     277Search::Xapian::[% class.class %] - [% class.header %]
     278
     279=head1 DESCRIPTION
     280
     281[% class.description -%]
     282=cut
     283
     284use 5.006;
     285use strict;
     286use warnings;
     287use Carp;
     288
     289require DynaLoader;
     290[% FOR cls IN class.children -%]
     291use Search::Xapian::[% cls.class %];
     292[% END %]
     293
     294our @ISA = qw(DynaLoader Search::Xapian::[% class.parent %]);
     295
     2961;
     297
     298# TMPL handleException
     299/* handleException function
     300 *
     301 * called in catch-blocks to croak or rethrow in perl-land
     302 */
     303
     304int handleException() {
     305
     306    try {
     307        throw;
     308[% FOR cls IN classes %]
     309    } catch (const Xapian::[% cls.class %] & error) {
     310        SV * errsv;
     311        errsv = get_sv("@", TRUE);
     312            sv_setref_pv(errsv, "Search::Xapian::[% cls.class %]", (void *) new [% cls.class %](error));
     313        croak(Nullch);
     314[% END %]
     315    } catch (const std::exception & error) {
     316        croak( "std::exception: %s", error.what());
     317    } catch (...) {
     318        croak("something terrible happend");
     319    }
     320}