Changeset 4ba05fcbd5ad0573c31ed6af7ac50f72f3d4b3e9

Show
Ignore:
Timestamp:
04/22/08 14:31:48 (9 months ago)
Author:
dave <dave@…>
Parents:
c929863ac8839608b81f31d8c7877cb11792961e
Children:
aeada46012e3db439288c894f0ca0dad1638cb57, f84102bad115887754ae1fafed8c072360deee9b
git-committer:
dave <dave@06fd6eb0-0002-0410-a719-e5602cce40bc> / 2008-04-22T04:31:48Z+0000
Message:

Improved documentaion in q_parser.y. Changed FrtQParser to FrtQueryParser?.

I've improved the documentation for the QueryParser in q_parser.y. It is far
from complete but much better than it was.

I also changed FrtQParser to FrtQueryParser? but FrtQParser is kept as an alias
and is still used in q_parser.y.

git-svn-id: svn+ssh://davebalmain.com/home/dave/repos/ferret/trunk@1033 06fd6eb0-0002-0410-a719-e5602cce40bc

Location:
c
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • c/include/internal.h

    rc92986 r4ba05f  
    270270#define QParser                 FrtQParser 
    271271#define Query                   FrtQuery 
     272#define QueryParser             FrtQueryParser 
    272273#define QueryType               FrtQueryType 
    273274#define RAMFile                 FrtRAMFile 
  • c/include/search.h

    rc92986 r4ba05f  
    899899} FrtFieldStack; 
    900900 
    901 typedef struct FrtQParser 
     901typedef struct FrtQueryParser 
    902902{ 
    903903    frt_mutex_t mutex; 
     
    929929    bool use_keywords : 1; 
    930930    bool use_typed_range_query : 1; 
    931 } FrtQParser; 
     931} FrtQueryParser; 
     932typedef FrtQueryParser FrtQParser; /* QParser is an alias for QueryParser */ 
    932933 
    933934extern FrtQParser *frt_qp_new(FrtHashSet *all_fields, FrtHashSet *def_fields, 
  • c/src/q_parser.c

    rc92986 r4ba05f  
    9999 
    100100/* Copy the first part of user declarations.  */ 
    101 #line 55 "src/q_parser.y" 
     101#line 84 "src/q_parser.y" 
    102102 
    103103#include <string.h> 
     
    150150#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 
    151151typedef union YYSTYPE 
    152 #line 84 "src/q_parser.y" 
     152#line 113 "src/q_parser.y" 
    153153{ 
    154154    Query *query; 
     
    170170 
    171171/* Copy the second part of user declarations.  */ 
    172 #line 92 "src/q_parser.y" 
     172#line 121 "src/q_parser.y" 
    173173 
    174174static int yylex(YYSTYPE *lvalp, QParser *qp); 
     
    551551 
    552552/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */ 
    553 static const yytype_uint8 yyrline[] = 
    554 { 
    555        0,   189,   189,   190,   192,   193,   194,   195,   197,   198, 
    556      199,   201,   202,   204,   205,   206,   207,   208,   209,   210, 
    557      212,   213,   214,   216,   218,   218,   220,   220,   220,   223, 
    558      224,   226,   227,   228,   229,   231,   232,   233,   234,   235, 
    559      237,   238,   239,   240,   241,   242,   243,   244,   245,   246, 
    560      247,   248 
     553static const yytype_uint16 yyrline[] = 
     554{ 
     555       0,   218,   218,   219,   221,   222,   223,   224,   226,   227, 
     556     228,   230,   231,   233,   234,   235,   236,   237,   238,   239, 
     557     241,   242,   243,   245,   247,   247,   249,   249,   249,   252, 
     558     253,   255,   256,   257,   258,   260,   261,   262,   263,   264, 
     559     266,   267,   268,   269,   270,   271,   272,   273,   274,   275, 
     560     276,   277 
    561561}; 
    562562#endif 
     
    12171217    { 
    12181218      case 27: /* "bool_q" */ 
    1219 #line 184 "src/q_parser.y" 
     1219#line 213 "src/q_parser.y" 
    12201220        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12211221#line 1222 "src/q_parser.c" 
    12221222        break; 
    12231223      case 28: /* "bool_clss" */ 
    1224 #line 186 "src/q_parser.y" 
     1224#line 215 "src/q_parser.y" 
    12251225        { if ((yyvaluep->bclss) && qp->destruct) bca_destroy((yyvaluep->bclss)); }; 
    12261226#line 1227 "src/q_parser.c" 
    12271227        break; 
    12281228      case 29: /* "bool_cls" */ 
    1229 #line 185 "src/q_parser.y" 
     1229#line 214 "src/q_parser.y" 
    12301230        { if ((yyvaluep->bcls) && qp->destruct) bc_deref((yyvaluep->bcls)); }; 
    12311231#line 1232 "src/q_parser.c" 
    12321232        break; 
    12331233      case 30: /* "boosted_q" */ 
    1234 #line 184 "src/q_parser.y" 
     1234#line 213 "src/q_parser.y" 
    12351235        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12361236#line 1237 "src/q_parser.c" 
    12371237        break; 
    12381238      case 31: /* "q" */ 
    1239 #line 184 "src/q_parser.y" 
     1239#line 213 "src/q_parser.y" 
    12401240        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12411241#line 1242 "src/q_parser.c" 
    12421242        break; 
    12431243      case 32: /* "term_q" */ 
    1244 #line 184 "src/q_parser.y" 
     1244#line 213 "src/q_parser.y" 
    12451245        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12461246#line 1247 "src/q_parser.c" 
    12471247        break; 
    12481248      case 33: /* "wild_q" */ 
    1249 #line 184 "src/q_parser.y" 
     1249#line 213 "src/q_parser.y" 
    12501250        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12511251#line 1252 "src/q_parser.c" 
    12521252        break; 
    12531253      case 34: /* "field_q" */ 
    1254 #line 184 "src/q_parser.y" 
     1254#line 213 "src/q_parser.y" 
    12551255        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12561256#line 1257 "src/q_parser.c" 
    12571257        break; 
    12581258      case 39: /* "phrase_q" */ 
    1259 #line 184 "src/q_parser.y" 
     1259#line 213 "src/q_parser.y" 
    12601260        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12611261#line 1262 "src/q_parser.c" 
    12621262        break; 
    12631263      case 40: /* "ph_words" */ 
    1264 #line 187 "src/q_parser.y" 
     1264#line 216 "src/q_parser.y" 
    12651265        { if ((yyvaluep->phrase) && qp->destruct) ph_destroy((yyvaluep->phrase)); }; 
    12661266#line 1267 "src/q_parser.c" 
    12671267        break; 
    12681268      case 41: /* "range_q" */ 
    1269 #line 184 "src/q_parser.y" 
     1269#line 213 "src/q_parser.y" 
    12701270        { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); }; 
    12711271#line 1272 "src/q_parser.c" 
     
    15781578    { 
    15791579        case 2: 
    1580 #line 189 "src/q_parser.y" 
     1580#line 218 "src/q_parser.y" 
    15811581    {   qp->result = (yyval.query) = NULL; } 
    15821582    break; 
    15831583 
    15841584  case 3: 
    1585 #line 190 "src/q_parser.y" 
     1585#line 219 "src/q_parser.y" 
    15861586    { T qp->result = (yyval.query) = get_bool_q((yyvsp[(1) - (1)].bclss)); E } 
    15871587    break; 
    15881588 
    15891589  case 4: 
    1590 #line 192 "src/q_parser.y" 
     1590#line 221 "src/q_parser.y" 
    15911591    { T (yyval.bclss) = first_cls((yyvsp[(1) - (1)].bcls)); E } 
    15921592    break; 
    15931593 
    15941594  case 5: 
    1595 #line 193 "src/q_parser.y" 
     1595#line 222 "src/q_parser.y" 
    15961596    { T (yyval.bclss) = add_and_cls((yyvsp[(1) - (3)].bclss), (yyvsp[(3) - (3)].bcls)); E } 
    15971597    break; 
    15981598 
    15991599  case 6: 
    1600 #line 194 "src/q_parser.y" 
     1600#line 223 "src/q_parser.y" 
    16011601    { T (yyval.bclss) = add_or_cls((yyvsp[(1) - (3)].bclss), (yyvsp[(3) - (3)].bcls)); E } 
    16021602    break; 
    16031603 
    16041604  case 7: 
    1605 #line 195 "src/q_parser.y" 
     1605#line 224 "src/q_parser.y" 
    16061606    { T (yyval.bclss) = add_default_cls(qp, (yyvsp[(1) - (2)].bclss), (yyvsp[(2) - (2)].bcls)); E } 
    16071607    break; 
    16081608 
    16091609  case 8: 
    1610 #line 197 "src/q_parser.y" 
     1610#line 226 "src/q_parser.y" 
    16111611    { T (yyval.bcls) = get_bool_cls((yyvsp[(2) - (2)].query), BC_MUST); E } 
    16121612    break; 
    16131613 
    16141614  case 9: 
    1615 #line 198 "src/q_parser.y" 
     1615#line 227 "src/q_parser.y" 
    16161616    { T (yyval.bcls) = get_bool_cls((yyvsp[(2) - (2)].query), BC_MUST_NOT); E } 
    16171617    break; 
    16181618 
    16191619  case 10: 
    1620 #line 199 "src/q_parser.y" 
     1620#line 228 "src/q_parser.y" 
    16211621    { T (yyval.bcls) = get_bool_cls((yyvsp[(1) - (1)].query), BC_SHOULD); E } 
    16221622    break; 
    16231623 
    16241624  case 12: 
    1625 #line 202 "src/q_parser.y" 
     1625#line 231 "src/q_parser.y" 
    16261626    { T if ((yyvsp[(1) - (3)].query)) sscanf((yyvsp[(3) - (3)].str),"%f",&((yyvsp[(1) - (3)].query)->boost));  (yyval.query)=(yyvsp[(1) - (3)].query); E } 
    16271627    break; 
    16281628 
    16291629  case 14: 
    1630 #line 205 "src/q_parser.y" 
     1630#line 234 "src/q_parser.y" 
    16311631    { T (yyval.query) = bq_new_max(true, qp->max_clauses); E } 
    16321632    break; 
    16331633 
    16341634  case 15: 
    1635 #line 206 "src/q_parser.y" 
     1635#line 235 "src/q_parser.y" 
    16361636    { T (yyval.query) = get_bool_q((yyvsp[(2) - (3)].bclss)); E } 
    16371637    break; 
    16381638 
    16391639  case 20: 
    1640 #line 212 "src/q_parser.y" 
     1640#line 241 "src/q_parser.y" 
    16411641    { FLDS((yyval.query), get_term_q(qp, field, (yyvsp[(1) - (1)].str))); Y} 
    16421642    break; 
    16431643 
    16441644  case 21: 
    1645 #line 213 "src/q_parser.y" 
     1645#line 242 "src/q_parser.y" 
    16461646    { FLDS((yyval.query), get_fuzzy_q(qp, field, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str))); Y} 
    16471647    break; 
    16481648 
    16491649  case 22: 
    1650 #line 214 "src/q_parser.y" 
     1650#line 243 "src/q_parser.y" 
    16511651    { FLDS((yyval.query), get_fuzzy_q(qp, field, (yyvsp[(1) - (2)].str), NULL)); Y} 
    16521652    break; 
    16531653 
    16541654  case 23: 
    1655 #line 216 "src/q_parser.y" 
     1655#line 245 "src/q_parser.y" 
    16561656    { FLDS((yyval.query), get_wild_q(qp, field, (yyvsp[(1) - (1)].str))); Y} 
    16571657    break; 
    16581658 
    16591659  case 24: 
    1660 #line 218 "src/q_parser.y" 
     1660#line 247 "src/q_parser.y" 
    16611661    { qp_pop_fields(qp); } 
    16621662    break; 
    16631663 
    16641664  case 25: 
    1665 #line 219 "src/q_parser.y" 
     1665#line 248 "src/q_parser.y" 
    16661666    { (yyval.query) = (yyvsp[(3) - (4)].query); } 
    16671667    break; 
    16681668 
    16691669  case 26: 
    1670 #line 220 "src/q_parser.y" 
     1670#line 249 "src/q_parser.y" 
    16711671    { qp_push_fields(qp, qp->all_fields, false); } 
    16721672    break; 
    16731673 
    16741674  case 27: 
    1675 #line 220 "src/q_parser.y" 
     1675#line 249 "src/q_parser.y" 
    16761676    { qp_pop_fields(qp); } 
    16771677    break; 
    16781678 
    16791679  case 28: 
    1680 #line 221 "src/q_parser.y" 
     1680#line 250 "src/q_parser.y" 
    16811681    { (yyval.query) = (yyvsp[(4) - (5)].query); } 
    16821682    break; 
    16831683 
    16841684  case 29: 
    1685 #line 223 "src/q_parser.y" 
     1685#line 252 "src/q_parser.y" 
    16861686    { (yyval.hashset) = first_field(qp, (yyvsp[(1) - (1)].str)); } 
    16871687    break; 
    16881688 
    16891689  case 30: 
    1690 #line 224 "src/q_parser.y" 
     1690#line 253 "src/q_parser.y" 
    16911691    { (yyval.hashset) = add_field(qp, (yyvsp[(3) - (3)].str));} 
    16921692    break; 
    16931693 
    16941694  case 31: 
    1695 #line 226 "src/q_parser.y" 
     1695#line 255 "src/q_parser.y" 
    16961696    { (yyval.query) = get_phrase_q(qp, (yyvsp[(2) - (3)].phrase), NULL); } 
    16971697    break; 
    16981698 
    16991699  case 32: 
    1700 #line 227 "src/q_parser.y" 
     1700#line 256 "src/q_parser.y" 
    17011701    { (yyval.query) = get_phrase_q(qp, (yyvsp[(2) - (5)].phrase), (yyvsp[(5) - (5)].str)); } 
    17021702    break; 
    17031703 
    17041704  case 33: 
    1705 #line 228 "src/q_parser.y" 
     1705#line 257 "src/q_parser.y" 
    17061706    { (yyval.query) = NULL; } 
    17071707    break; 
    17081708 
    17091709  case 34: 
    1710 #line 229 "src/q_parser.y" 
     1710#line 258 "src/q_parser.y" 
    17111711    { (yyval.query) = NULL; (void)(yyvsp[(4) - (4)].str);} 
    17121712    break; 
    17131713 
    17141714  case 35: 
    1715 #line 231 "src/q_parser.y" 
     1715#line 260 "src/q_parser.y" 
    17161716    { (yyval.phrase) = ph_first_word((yyvsp[(1) - (1)].str)); } 
    17171717    break; 
    17181718 
    17191719  case 36: 
    1720 #line 232 "src/q_parser.y" 
     1720#line 261 "src/q_parser.y" 
    17211721    { (yyval.phrase) = ph_first_word(NULL); } 
    17221722    break; 
    17231723 
    17241724  case 37: 
    1725 #line 233 "src/q_parser.y" 
     1725#line 262 "src/q_parser.y" 
    17261726    { (yyval.phrase) = ph_add_word((yyvsp[(1) - (2)].phrase), (yyvsp[(2) - (2)].str)); } 
    17271727    break; 
    17281728 
    17291729  case 38: 
    1730 #line 234 "src/q_parser.y" 
     1730#line 263 "src/q_parser.y" 
    17311731    { (yyval.phrase) = ph_add_word((yyvsp[(1) - (3)].phrase), NULL); } 
    17321732    break; 
    17331733 
    17341734  case 39: 
    1735 #line 235 "src/q_parser.y" 
     1735#line 264 "src/q_parser.y" 
    17361736    { (yyval.phrase) = ph_add_multi_word((yyvsp[(1) - (3)].phrase), (yyvsp[(3) - (3)].str));  } 
    17371737    break; 
    17381738 
    17391739  case 40: 
    1740 #line 237 "src/q_parser.y" 
     1740#line 266 "src/q_parser.y" 
    17411741    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str),  (yyvsp[(3) - (4)].str),  true,  true)); Y} 
    17421742    break; 
    17431743 
    17441744  case 41: 
    1745 #line 238 "src/q_parser.y" 
     1745#line 267 "src/q_parser.y" 
    17461746    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str),  (yyvsp[(3) - (4)].str),  true,  false)); Y} 
    17471747    break; 
    17481748 
    17491749  case 42: 
    1750 #line 239 "src/q_parser.y" 
     1750#line 268 "src/q_parser.y" 
    17511751    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str),  (yyvsp[(3) - (4)].str),  false, true)); Y} 
    17521752    break; 
    17531753 
    17541754  case 43: 
    1755 #line 240 "src/q_parser.y" 
     1755#line 269 "src/q_parser.y" 
    17561756    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str),  (yyvsp[(3) - (4)].str),  false, false)); Y} 
    17571757    break; 
    17581758 
    17591759  case 44: 
    1760 #line 241 "src/q_parser.y" 
     1760#line 270 "src/q_parser.y" 
    17611761    { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (3)].str),  false, false)); Y} 
    17621762    break; 
    17631763 
    17641764  case 45: 
    1765 #line 242 "src/q_parser.y" 
     1765#line 271 "src/q_parser.y" 
    17661766    { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (3)].str),  false, true)); Y} 
    17671767    break; 
    17681768 
    17691769  case 46: 
    1770 #line 243 "src/q_parser.y" 
     1770#line 272 "src/q_parser.y" 
    17711771    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (3)].str),  NULL,true,  false)); Y} 
    17721772    break; 
    17731773 
    17741774  case 47: 
    1775 #line 244 "src/q_parser.y" 
     1775#line 273 "src/q_parser.y" 
    17761776    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (3)].str),  NULL,false, false)); Y} 
    17771777    break; 
    17781778 
    17791779  case 48: 
    1780 #line 245 "src/q_parser.y" 
     1780#line 274 "src/q_parser.y" 
    17811781    { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (2)].str),  false, false)); Y} 
    17821782    break; 
    17831783 
    17841784  case 49: 
    1785 #line 246 "src/q_parser.y" 
     1785#line 275 "src/q_parser.y" 
    17861786    { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(3) - (3)].str),  false, true)); Y} 
    17871787    break; 
    17881788 
    17891789  case 50: 
    1790 #line 247 "src/q_parser.y" 
     1790#line 276 "src/q_parser.y" 
    17911791    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(3) - (3)].str),  NULL,true,  false)); Y} 
    17921792    break; 
    17931793 
    17941794  case 51: 
    1795 #line 248 "src/q_parser.y" 
     1795#line 277 "src/q_parser.y" 
    17961796    { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (2)].str),  NULL,false, false)); Y} 
    17971797    break; 
     
    20132013 
    20142014 
    2015 #line 250 "src/q_parser.y" 
     2015#line 279 "src/q_parser.y" 
    20162016 
    20172017 
     
    24822482} 
    24832483 
     2484/** 
     2485 * Build a phrase query for a single field. It might seem like a better idea 
     2486 * to build the PhraseQuery once and duplicate it for each field but this 
     2487 * would be buggy in the case of PerFieldAnalyzers in which case a different 
     2488 * tokenizer could be used for each field. 
     2489 * 
     2490 * Note that the query object returned by this method is not always a 
     2491 * PhraseQuery. If there is only one term in the query then the query is 
     2492 * simplified to a TermQuery. If there are multiple terms but only a single 
     2493 * position, then a MultiTermQuery is retured. 
     2494 * 
     2495 * Note that each word in the query gets tokenized. Unlike get_term_q, if the 
     2496 * word gets tokenized into more than one token, the rest of the tokens are 
     2497 * ignored. 
     2498 */ 
    24842499static Query *get_phrase_query(QParser *qp, char *field, 
    24852500                               Phrase *phrase, char *slop_str) 
     
    25022517            for (i = 0; i < word_count; i++) { 
    25032518                token = ts_next(get_cached_ts(qp, field, words[i])); 
    2504                 free(words[i]); 
    25052519                if (token) { 
     2520                    free(words[i]); 
    25062521                    last_word = words[i] = estrdup(token->text); 
    25072522                    ++term_cnt; 
    25082523                } 
    25092524                else { 
    2510                     words[i] = estrdup(""); 
     2525                    /* empty words will later be ignored */ 
     2526                    words[i][0] = '\0'; 
    25112527                } 
    25122528            } 
     
    25222538                    q = multi_tq_new_conf(field, term_cnt, 0.0); 
    25232539                    for (i = 0; i < word_count; i++) { 
     2540                        /* ignore empty words */ 
    25242541                        if (words[i][0]) { 
    25252542                            multi_tq_add_term(q, words[i]); 
     
    25872604} 
    25882605 
     2606/** 
     2607 * Get a phrase query from the Phrase object. The Phrase object is built up by 
     2608 * the query parser as the all PhraseQuery didn't work well for this. Once the 
     2609 * PhraseQuery has been built the Phrase object needs to be destroyed. 
     2610 */ 
    25892611static Query *get_phrase_q(QParser *qp, Phrase *phrase, char *slop_str) 
    25902612{ 
     
    25952617} 
    25962618 
     2619/** 
     2620 * Gets a RangeQuery object. 
     2621 * 
     2622 * Just like with WildCardQuery, RangeQuery needs to downcase its terms if the 
     2623 * tokenizer also downcased its terms. 
     2624 */ 
    25972625static Query *get_r_q(QParser *qp, char *field, char *from, char *to, 
    25982626                      bool inc_lower, bool inc_upper) 
    25992627{ 
    26002628    Query *rq; 
    2601     if (qp->wild_lower) { 
     2629    if (qp->wild_lower 
     2630        && (!qp->tokenized_fields || hs_exists(qp->tokenized_fields, field))) { 
    26022631        if (from) { 
    26032632            lower_str(from); 
     
    26082637    } 
    26092638/* 
     2639 * terms don't get tokenized as it doesn't really make sense to do so for 
     2640 * range queries. 
     2641 
    26102642    if (from) { 
    26112643        TokenStream *stream = get_cached_ts(qp, field, from); 
     
    26262658} 
    26272659 
     2660/** 
     2661 * Every time the query parser sees a new field modifier ("field1|field2:") 
     2662 * it pushes a new FieldStack object onto the stack and sets its fields to the 
     2663 * fields specified in the fields modifier. If the field modifier is '*', 
     2664 * fs->fields is set to all_fields. fs->fields is set to +qp->def_field+ at 
     2665 * the bottom of the stack (ie the very first set of fields pushed onto the 
     2666 * stack). 
     2667 */ 
    26282668static void qp_push_fields(QParser *self, HashSet *fields, bool destroy) 
    26292669{ 
     
    26382678} 
    26392679 
     2680/** 
     2681 * Pops the top of the fields stack and frees any memory used by it. This will 
     2682 * get called when query modified by a field modifier ("field1|field2:") has 
     2683 * been fully parsed and the field specifier no longer applies. 
     2684 */ 
    26402685static void qp_pop_fields(QParser *self) 
    26412686{ 
     
    26522697} 
    26532698 
     2699/** 
     2700 * Free all memory allocated by the QueryParser. 
     2701 */ 
    26542702void qp_destroy(QParser *self) 
    26552703{ 
     
    26742722} 
    26752723 
     2724/** 
     2725 * Creates a new QueryParser setting all boolean parameters to their defaults. 
     2726 * If +def_fields+ is NULL then +all_fields+ is used in place of +def_fields+. 
     2727 * Not also that this method ensures that all fields that exist in 
     2728 * +def_fields+ must also exist in +all_fields+. This should make sense. 
     2729 */ 
    26762730QParser *qp_new(HashSet *all_fields, HashSet *def_fields, 
    26772731                HashSet *tokenized_fields, Analyzer *analyzer) 
     
    27082762    self->ts_cache = h_new_str(NULL, (free_ft)&ts_deref); 
    27092763    self->buf_index = 0; 
    2710     self->dynbuf = 0; 
     2764    self->dynbuf = NULL; 
    27112765    self->non_tokenizer = non_tokenizer_new(); 
    27122766    mutex_init(&self->mutex, NULL); 
     
    27172771static const char *PHRASE_CHARS = "<>|\""; 
    27182772 
    2719 static void str_insert(char *str, int len, char chr) 
     2773/** 
     2774 * +str_insert_char+ inserts a character at the beginning of a string by 
     2775 * shifting the rest of the string right. 
     2776 */ 
     2777static void str_insert_char(char *str, int len, char chr) 
    27202778{ 
    27212779    memmove(str+1, str, len*sizeof(char)); 
     
    27232781} 
    27242782 
    2725 /***************************************************************************** 
    2726  * qp_clean_str method which basically scans the query string and ensures that 
    2727  * all open and close parentheses '()' and quotes '"' are balanced. It does 
    2728  * this be inserting or appending extra parentheses or quotes which is not 
    2729  * necessarily going to be exactly what the user wanted but it will help 
    2730  * prevent the parser from failing so it's the best we can do at this stage. 
    2731  * It also checks  
    2732  *****************************************************************************/ 
     2783/** 
     2784 * +qp_clean_str+ basically scans the query string and ensures that all open 
     2785 * and close parentheses '()' and quotes '"' are balanced. It does this by 
     2786 * inserting or appending extra parentheses or quotes to the string. This 
     2787 * obviously won't necessarily be exactly what the user wanted but we are 
     2788 * never going to know that anyway. The main job of this method is to help the 
     2789 * query at least parse correctly. 
     2790 * 
     2791 * It also checks that all special characters within phrases (ie between 
     2792 * quotes) are escaped correctly unless they have meaning within a phrase 
     2793 * ( <>,|," ). Note that '<' and '>' will also be escaped unless the appear 
     2794 * together like so; '<>'. 
     2795 */ 
    27332796char *qp_clean_str(char *str) 
    27342797{ 
     
    27492812            } 
    27502813            *nsp++ = b; 
    2751             /* \\ has escaped itself so has no power. Assign pb random char : */ 
    2752             pb = ((b == '\\') ? ':' : b); 
     2814            /* \ has escaped itself so has no power. Assign pb random char 'r' */ 
     2815            pb = ((b == '\\') ? 'r' : b); 
    27532816            continue; 
    27542817        } 
     
    27752838                if (!quote_open) { 
    27762839                    if (br_cnt == 0) { 
    2777                         str_insert(new_str, (int)(nsp - new_str), '('); 
     2840                        str_insert_char(new_str, (int)(nsp - new_str), '('); 
    27782841                        nsp++; 
    27792842                    } 
     
    28202883} 
    28212884 
     2885/** 
     2886 * Takes a string and finds whatever tokens it can using the QueryParser's 
     2887 * analyzer. It then turns these tokens (if any) into a boolean query. If it 
     2888 * fails to find any tokens, this method will return NULL. 
     2889 */ 
    28222890static Query *qp_get_bad_query(QParser *qp, char *str) 
    28232891{ 
     
    28282896} 
    28292897 
     2898/** 
     2899 * +qp_parse+ takes a string and turns it into a Query object using Ferret's 
     2900 * query language. It must either raise an error or return a query object. It 
     2901 * must not return NULL. If the yacc parser fails it will use a very basic 
     2902 * boolean query parser which takes whatever tokens it can find in the query 
     2903 * and terns them into a boolean query on the default fields. 
     2904 */ 
    28302905Query *qp_parse(QParser *self, char *qstr) 
    28312906{ 
    28322907    Query *result = NULL; 
    28332908    mutex_lock(&self->mutex); 
     2909    /* if qp->fields_top->next is not NULL we have a left over field-stack 
     2910     * object that was not popped during the last query parse */ 
     2911    assert(NULL == self->fields_top->next);