Show
Ignore:
Timestamp:
07/21/08 23:51:24 (6 months ago)
Author:
karpet
Message:

change top-level tokenizer functions to use same signature so that we can more easily
swap between them. Change tests to use new iterator style by default (-t option to swish_lint).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libswish3/trunk/src/libswish3/libswish3.h

    r2142 r2148  
    353353    boolean                tokenize;           // should we parse into WordList 
    354354    boolean                tokenlist;          // use new tokenizer 
    355     swish_WordList*      (*tokenizer) (swish_Analyzer*, xmlChar*, ...); 
     355    int                  (*tokenizer) (swish_3*, xmlChar*, ...); 
    356356    xmlChar*             (*stemmer)   (xmlChar*); 
    357357    unsigned int           lc;                 // should tokens be lowercased 
     
    552552swish_WordList *    swish_init_wordlist(); 
    553553void                swish_free_wordlist(swish_WordList * list); 
    554 swish_WordList *    swish_tokenize( swish_Analyzer * analyzer, xmlChar * str, ... ); 
    555  
    556 swish_WordList *    swish_tokenize_utf8_string( 
    557                                       swish_Analyzer * analyzer,   
     554int                 swish_tokenize( swish_3 * s3, xmlChar * str, ... ); 
     555 
     556int                 swish_tokenize_utf8_string( 
     557                                      swish_3 * s3,   
    558558                                      xmlChar * str, 
     559                                      swish_WordList * wl, 
    559560                                      unsigned int offset, 
    560561                                      unsigned int word_pos, 
     
    563564                                      ); 
    564565 
    565 swish_WordList *    swish_tokenize_ascii_string(    
    566                                       swish_Analyzer * analyzer,  
     566int                 swish_tokenize_ascii_string(    
     567                                      swish_3 * s3, 
    567568                                      xmlChar * str, 
     569                                      swish_WordList * wl, 
    568570                                      unsigned int offset, 
    569571                                      unsigned int word_pos, 
     
    572574                                      ); 
    573575 
    574 swish_WordList *    swish_tokenize_regex( 
    575                                       swish_Analyzer * analyzer,  
     576int                 swish_tokenize_regex( 
     577                                      swish_3 * s3, 
    576578                                      xmlChar * str, 
     579                                      swish_WordList * wl, 
    577580                                      unsigned int offset, 
    578581                                      unsigned int word_pos, 
     
    618621void                swish_free_token_iterator( swish_TokenIterator *ti ); 
    619622swish_Token *       swish_next_token( swish_TokenIterator *it ); 
    620 int                 swish_tokenize3(    swish_3 *s3,  
    621                                         swish_TokenList * tl,  
    622                                         xmlChar *buf,  
    623                                         swish_MetaName *meta, 
    624                                         xmlChar *context ); 
     623int                 swish_tokenize3( swish_3 *s3, xmlChar *buf, ... ); 
    625624int                 swish_tokenize3_ascii(     
    626625                                        swish_3 *s3,  
     626                                        xmlChar *buf,  
    627627                                        swish_TokenList * tl,  
    628                                         xmlChar *buf,  
    629628                                        swish_MetaName *meta, 
    630629                                        xmlChar *context ); 
    631630int                 swish_tokenize3_utf8(     
    632631                                        swish_3 *s3,  
    633                                         swish_TokenList * tl,  
    634632                                        xmlChar *buf,  
     633                                        swish_TokenList * tl, 
    635634                                        swish_MetaName *meta, 
    636635                                        xmlChar *context ); 
  • libswish3/trunk/src/libswish3/parser.c

    r2140 r2148  
    1616 *  along with libswish3; if not, write to the Free Software 
    1717 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
    18  */ 
     18*/ 
    1919 
    2020/*  
     
    3030 * all the mb*() functions rely on locale to recognize multi-byte strings 
    3131 * 
    32  */ 
     32*/ 
    3333 
    3434#include <stdio.h> 
     
    9393/*  
    9494 * SAX2 support  
    95  */ 
     95*/ 
    9696static void mystartElementNs( 
    9797    void *parser_data, 
     
    181181/*  
    182182 * parsing fh/buffer headers  
    183  */ 
     183*/ 
    184184typedef struct 
    185185{ 
     
    208208); 
    209209 
    210  
    211210/* tag tracker */ 
    212211static xmlChar *flatten_tag_stack( 
     
    237236 *                end prototypes 
    238237 ***********************************************************************/ 
    239   
     238 
    240239swish_Parser * 
    241240swish_init_parser( 
     
    248247    p->ref_cnt = 0; 
    249248 
    250     /* 
     249/* 
    251250     * libxml2 stuff  
    252      */ 
     251*/ 
    253252    xmlInitParser(); 
    254253    xmlSubstituteEntitiesDefault(1);    /* resolve text entities */ 
    255254 
    256     /* 
     255/* 
    257256     * debugging help  
    258      */ 
     257*/ 
    259258    get_env_vars(); 
    260259 
     
    286285 * turn the literal xml/html tag into a swish tag for matching against 
    287286 * metanames and properties  
    288  */ 
     287*/ 
    289288static xmlChar * 
    290289build_tag( 
     
    314313    metacontent = NULL; 
    315314 
    316     /* 
     315/* 
    317316     * normalize all tags  
    318      */ 
     317*/ 
    319318    swishtag = swish_str_tolower(tag); 
    320319 
    321     /* 
     320/* 
    322321     * html tags  
    323      */ 
     322*/ 
    324323    if (parser_data->is_html) { 
    325324 
    326         /* 
     325/* 
    327326           TODO config features about img tags and a/href tags  
    328          */ 
     327*/ 
    329328        if (xmlStrEqual(swishtag, (xmlChar *)"br") 
    330329            || xmlStrEqual(swishtag, (xmlChar *)"img")) { 
     
    339338            else if (!element->isinline) { 
    340339 
    341                 /* 
     340/* 
    342341                 * need to bump word_pos so we don't match across block * 
    343342                 * elements  
    344                  */ 
     343*/ 
    345344 
    346345            } 
    347346        } 
    348347 
    349         /* 
     348/* 
    350349         * is this an HTML <meta> tag? treat 'name' attribute as a tag * 
    351350         * and 'content' attribute as the tag content * we assume 'name' 
    352351         * and 'content' are always in english.  
    353          */ 
     352*/ 
    354353 
    355354        if (atts != 0) { 
     
    361360                if (xmlStrEqual(atts[i], (xmlChar *)"name")) { 
    362361 
    363                     /* 
     362/* 
    364363                     * SWISH_DEBUG_MSG("found name: %s", atts[i+1]);  
    365                      */ 
     364*/ 
    366365                    metaname = (xmlChar *)atts[i + 1]; 
    367366                } 
     
    369368                else if (xmlStrEqual(atts[i], (xmlChar *)"content")) { 
    370369 
    371                     /* 
     370/* 
    372371                     * SWISH_DEBUG_MSG("found content: %s", atts[i+1]);  
    373                      */ 
     372*/ 
    374373                    metacontent = (xmlChar *)atts[i + 1]; 
    375374                } 
     
    382381                SWISH_DEBUG_MSG("found HTML meta: %s => %s", metaname, metacontent); 
    383382 
    384             /* 
     383/* 
    385384             * do not match across metas  
    386              */ 
     385*/ 
    387386            parser_data->bump_word = 1; 
    388387            open_tag(parser_data, metaname, NULL); 
     
    395394    } 
    396395 
    397     /* 
     396/* 
    398397     * xml tags  
    399      */ 
     398*/ 
    400399    else { 
    401400 
    402         /* 
     401/* 
    403402         * TODO make this configurable ala swish2  
    404          */ 
     403*/ 
    405404 
    406405        parser_data->bump_word = 1; 
     
    422421                attr_val_lower = swish_str_tolower(atts[i + 1]); 
    423422 
    424                 /* 
     423/* 
    425424                   is it one of ours?  
    426                  */ 
     425*/ 
    427426                for (j = 0; j < strlist->n; j++) { 
    428427                    if (xmlStrEqual(strlist->word[j], attr_lower)) { 
     
    430429                            SWISH_DEBUG_MSG("found %s: %s", attr_lower, attr_val_lower); 
    431430 
    432                         // eligible attribute name 
    433                         size = xmlStrlen(swishtag) + xmlStrlen(attr_val_lower) + 2;     // dot + NULL 
     431/*  eligible attribute name */ 
     432                        size = xmlStrlen(swishtag) + xmlStrlen(attr_val_lower) + 2;     /*  dot + NULL */ 
    434433                        metaname = swish_xmalloc(size + 1); 
    435434                        snprintf((char *)metaname, size, "%s.%s", (char *)swishtag, 
     
    449448    } 
    450449 
    451     /* 
     450/* 
    452451     * change our internal name for this tag if it is aliased in config  
    453      */ 
     452*/ 
    454453    alias = swish_hash_fetch(parser_data->s3->config->tag_aliases, swishtag); 
    455454    if (alias) { 
    456455 
    457         /* 
     456/* 
    458457         * SWISH_DEBUG_MSG("%s alias -> %s", swishtag, alias);  
    459          */ 
     458*/ 
    460459        swish_xfree(swishtag); 
    461460        swishtag = swish_xstrdup(alias); 
     
    482481                        xmlBufferContent(parser_data->meta_buf), parser_data->word_pos); 
    483482 
    484     /* 
     483/* 
    485484     * since we only flush the buffer when metaname changes, and we do 
    486485     * not want to match across metanames, bump the word_pos here before  
    487486     * parsing the string and making the tmp wordlist  
    488      */ 
     487*/ 
    489488    if (parser_data->word_pos) 
    490489        parser_data->word_pos++; 
    491490 
    492     /* 
     491/* 
    493492     * add meta_buf as-is to metanames buffer under current tag. this 
    494493     * gives us both tokens and raw text de-tagged but organized by 
    495494     * metaname.  
    496      */ 
     495*/ 
    497496    swish_add_buf_to_nb(parser_data->metanames, metaname, parser_data->meta_buf, 
    498497                        (xmlChar *)SWISH_META_CONNECTOR, 0, 1); 
    499498 
    500     /* 
     499/* 
    501500     *  add to every metaname on the stack. 
    502501     *  Disabling this for now, as it ought to be up the handler() to decide 
    503502     *  to index a token under multiple metanames, and we associate context 
    504503     *  with the WordList 
    505      */ 
     504*/ 
    506505 
    507506    if (parser_data->s3->config->flags->context_as_meta) { 
    508507        for (s->temp = s->head; s->temp != NULL; s->temp = s->temp->next) { 
    509             if (xmlStrEqual(s->temp->baked, metaname))  // already added 
     508            if (xmlStrEqual(s->temp->baked, metaname))  /*  already added */ 
    510509                continue; 
    511510 
     
    527526/*  
    528527 * SAX2 callback  
    529  */ 
     528*/ 
    530529static void 
    531530mystartDocument( 
     
    534533{ 
    535534 
    536     /* 
     535/* 
    537536     * swish_ParserData *parser_data = (swish_ParserData *) data;  
    538      */ 
     537*/ 
    539538 
    540539    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
     
    545544/*  
    546545 * SAX2 callback  
    547  */ 
     546*/ 
    548547static void 
    549548myendDocument( 
     
    555554        SWISH_DEBUG_MSG("endDocument()"); 
    556555 
    557     /* 
     556/* 
    558557     * whatever's left  
    559      */ 
     558*/ 
    560559    flush_buffer(parser_data, (xmlChar *)SWISH_DEFAULT_METANAME, 
    561560                 (xmlChar *)SWISH_DEFAULT_METANAME); 
     
    565564/*  
    566565 * SAX1 callback  
    567  */ 
     566*/ 
    568567static void 
    569568mystartElement( 
     
    578577/*  
    579578 * SAX1 callback  
    580  */ 
     579*/ 
    581580static void 
    582581myendElement( 
     
    590589/*  
    591590 * SAX2 handler  
    592  */ 
     591*/ 
    593592static void 
    594593mystartElementNs( 
     
    630629            for (i = 0; (atts[i] != NULL); i += 2) { 
    631630                SWISH_DEBUG_MSG(" att: %s=%s", atts[i], atts[i + 1]); 
    632                 //SWISH_DEBUG_MSG(" att: %s=", atts[i++], atts[i] || ""); 
     631/* SWISH_DEBUG_MSG(" att: %s=", atts[i++], atts[i] || ""); */ 
    633632            } 
    634633        } 
     
    644643/*  
    645644 * SAX2 handler  
    646  */ 
     645*/ 
    647646static void 
    648647myendElementNs( 
     
    674673        SWISH_DEBUG_MSG("checking config for '%s' in watched tags", parser_data->tag); 
    675674 
    676     /* 
     675/* 
    677676     * set property if this tag is configured for it  
    678      */ 
     677*/ 
    679678    if (swish_hash_exists(parser_data->s3->config->properties, parser_data->tag)) { 
    680679        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    681680            SWISH_DEBUG_MSG(" %s = new property", parser_data->tag); 
    682681 
    683         add_stack_to_prop_buf(NULL, parser_data); /* NULL means all properties in the stack are added */ 
     682        add_stack_to_prop_buf(NULL, parser_data);       /* NULL means all properties in the stack are added */ 
    684683        xmlBufferEmpty(parser_data->prop_buf); 
    685684 
     
    690689    } 
    691690 
    692     /* 
     691/* 
    693692     * likewise for metastack  
    694      */ 
     693*/ 
    695694    if (swish_hash_exists(parser_data->s3->config->metanames, parser_data->tag)) { 
    696695        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
     
    719718    parser_data = (swish_ParserData *)data; 
    720719 
    721     /* 
     720/* 
    722721     * lowercase all names for comparison against metanames (which are 
    723722     * also * lowercased)  
    724      */ 
     723*/ 
    725724    if (parser_data->tag != NULL) 
    726725        swish_xfree(parser_data->tag); 
     
    744743    } 
    745744 
    746     /* 
     745/* 
    747746     * turn flag off so next open_tag() can evaluate  
    748      */ 
     747*/ 
    749748    parser_data->bump_word = 0; 
    750749 
     
    753752/*  
    754753 * handle all characters in doc  
    755  */ 
     754*/ 
    756755static void 
    757756buffer_characters( 
     
    765764    xmlBufferPtr buf = parser_data->meta_buf; 
    766765 
    767     /* 
     766/* 
    768767     * why not wchar_t ? len is number of bytes, not number of 
    769768     * characters, so xmlChar (i.e., char) works 
    770      */ 
    771  
    772     /* 
     769*/ 
     770 
     771/* 
    773772     * SWISH_DEBUG_MSG( "sizeof output buf is %d; len was %d\n", sizeof(output), 
    774773     * len ); 
    775      */ 
    776  
    777     /* 
     774*/ 
     775 
     776/* 
    778777     * SWISH_DEBUG_MSG( "characters");  
    779      */ 
     778*/ 
    780779 
    781780    for (i = 0; i < len; i++) { 
    782781 
    783         /* 
     782/* 
    784783         * fprintf(stderr, "%c", ch[i]);  
    785          */ 
     784*/ 
    786785        output[i] = ch[i]; 
    787786    } 
     
    795794    if (parser_data->bump_word && xmlBufferLength(parser_data->prop_buf)) { 
    796795 
    797         /* 
     796/* 
    798797         * SWISH_DEBUG_MSG(" appending ' ' to prop_buf");  
    799          */ 
     798*/ 
    800799        swish_append_buffer(parser_data->prop_buf, (xmlChar *)" ", 1); 
    801800    } 
    802801 
    803     /* 
     802/* 
    804803     * SWISH_DEBUG_MSG(" appending '%s' to prop_buf", output);  
    805      */ 
     804*/ 
    806805    swish_append_buffer(parser_data->prop_buf, output, len); 
    807806 
     
    810809/*  
    811810 * SAX2 callback  
    812  */ 
     811*/ 
    813812static void 
    814813mycharacters( 
     
    826825/*  
    827826 * SAX2 callback  
    828  */ 
     827*/ 
    829828static void 
    830829mycomments( 
     
    835834    int len = strlen((char *)(char *)ch); 
    836835 
    837     /* 
     836/* 
    838837     * TODO: make comments indexing optional  
    839      */ 
    840  
    841     /* 
     838*/ 
     839 
     840/* 
    842841     * TODO: enable noindex option  
    843      */ 
     842*/ 
    844843    return; 
    845844 
     
    849848/*  
    850849 * SAX2 callback  
    851  */ 
     850*/ 
    852851static void 
    853852myerr( 
     
    860859    va_list args; 
    861860    char str[1000]; 
    862      
     861 
    863862    if (!SWISH_PARSER_WARNINGS) 
    864863        return; 
    865864 
    866865    parser_data = (swish_ParserData *)data; 
    867      
     866 
    868867    SWISH_WARN("libxml2 error for %s:", parser_data->docinfo->uri); 
    869      
     868 
    870869    va_start(args, msg); 
    871870    vsnprintf((char *)str, 1000, (char *)msg, args); 
     
    876875/*  
    877876 * SAX2 callback  
    878  */ 
     877*/ 
    879878static void 
    880879mywarn( 
     
    887886    va_list args; 
    888887    char str[1000]; 
    889      
     888 
    890889    if (!SWISH_PARSER_WARNINGS) 
    891890        return; 
    892891 
    893892    parser_data = (swish_ParserData *)user_data; 
    894      
     893 
    895894    SWISH_WARN("libxml2 warning for %s:", parser_data->docinfo->uri); 
    896      
     895 
    897896    va_start(args, msg); 
    898897    vsnprintf((char *)str, 1000, (char *)msg, args); 
     
    903902/*  
    904903 * SAX2 handler struct for html and xml parsing  
    905  */ 
     904*/ 
    906905 
    907906xmlSAXHandler my_parser = { 
     
    965964        SWISH_DEBUG_MSG("%s -- using %s parser", parser_data->docinfo->uri, parser); 
    966965 
    967     /* 
     966/* 
    968967     * slurp file if not already in memory  
    969      */ 
     968*/ 
    970969    if (filename && !buffer) { 
    971970        buffer = swish_slurp_file_len(filename, (long)parser_data->docinfo->size); 
     
    989988    if (filename) { 
    990989 
    991         /* 
     990/* 
    992991         * SWISH_DEBUG_MSG( "freeing buffer");  
    993          */ 
     992*/ 
    994993        swish_xfree(buffer); 
    995994    } 
     
    10251024    ptr->metanames = swish_init_nb(s3->config->metanames); 
    10261025    ptr->metanames->ref_cnt++; 
    1027  
    1028     /* 
     1026     
     1027/* 
     1028*   pick a tokenizer if one has not been explicitly set 
     1029*/ 
     1030    if (s3->analyzer->tokenizer == NULL) { 
     1031        if (s3->analyzer->tokenlist) { 
     1032            s3->analyzer->tokenizer = (&swish_tokenize3); 
     1033        } 
     1034        else { 
     1035            s3->analyzer->tokenizer = (&swish_tokenize); 
     1036        } 
     1037    } 
     1038 
     1039/* 
    10291040     * prime the stacks  
    1030      */ 
     1041*/ 
    10311042    ptr->metastack = (swish_TagStack *)swish_xmalloc(sizeof(swish_TagStack)); 
    10321043    ptr->metastack->name = "MetaStack"; 
     
    10441055    push_tag_stack(ptr->propstack, (xmlChar *)"_", (xmlChar *)"_"); 
    10451056 
    1046     /* 
     1057/* 
    10471058     * no such property just to seed stack  
    1048      */ 
    1049  
    1050     /* 
     1059*/ 
     1060 
     1061/* 
    10511062     * gets toggled per-tag  
    1052      */ 
     1063*/ 
    10531064    ptr->bump_word = 1; 
    10541065 
    1055     /* 
     1066/* 
    10561067     * toggle  
    1057      */ 
     1068*/ 
    10581069    ptr->no_index = 0; 
    10591070 
    1060     /* 
     1071/* 
    10611072     * shortcut rather than looking parser up in hash for each tag event  
    1062      */ 
     1073*/ 
    10631074    ptr->is_html = 0; 
    10641075 
    1065     /* 
     1076/* 
    10661077     * must be zero so that ++ works ok on first word  
    1067      */ 
     1078*/ 
    10681079    ptr->word_pos = 0; 
    10691080 
    1070     /* 
     1081/* 
    10711082     * always start at first byte  
    1072      */ 
     1083*/ 
    10731084    ptr->offset = 0; 
    10741085 
    1075     /* 
     1086/* 
    10761087     * pointer to the xmlParserCtxt since we want to free it only after 
    10771088     * we're completely done with it. NOTE this is a change per libxml2 
    10781089     * vers > 2.6.16  
    1079      */ 
     1090*/ 
    10801091    ptr->ctxt = NULL; 
    10811092 
     
    10971108        SWISH_DEBUG_MSG("freeing swish_ParserData"); 
    10981109 
    1099     /* 
     1110/* 
    11001111     * dec ref count for shared ptr  
    1101      */ 
     1112*/ 
    11021113    ptr->s3->ref_cnt--; 
    11031114 
    1104     /* 
     1115/* 
    11051116     * Pop the stacks  
    1106      */ 
     1117*/ 
    11071118    while ((st = pop_tag_stack(ptr->metastack)) != NULL) { 
    11081119        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
     
    11841195        swish_free_wordlist(ptr->wordlist); 
    11851196    } 
    1186      
     1197 
    11871198    if (ptr->token_iterator != NULL) { 
    11881199 
     
    12381249    while (j < SWISH_MAX_HEADERS && i <= SWISH_MAXSTRLEN) { 
    12391250 
    1240         /* 
     1251/* 
    12411252         * SWISH_DEBUG_MSG( "i = %d j = %d k = %d", i, j, k);  
    1242          */ 
     1253*/ 
    12431254 
    12441255        if (buf[k] == '\n') { 
     
    12471258        line[i] = buf[k]; 
    12481259 
    1249         /* 
     1260/* 
    12501261         * fprintf(stderr, "%c", line[i]);  
    1251          */ 
     1262*/ 
    12521263        i++; 
    12531264        k++; 
     
    12591270            h->nlines++; 
    12601271 
    1261             /* 
     1272/* 
    12621273             * get to the next char no matter what, then check if == '\n'  
    1263              */ 
     1274*/ 
    12641275            k++; 
    12651276 
    12661277            if (buf[k] == '\n') { 
    12671278 
    1268                 /* 
     1279/* 
    12691280                 * fprintf(stderr, "found blank line at byte %d\n", k);  
    1270                  */ 
     1281*/ 
    12711282                h->body_start = k + 1; 
    12721283                break; 
     
    14031414                SWISH_WARN("Failed to find path name in Content-Type header '%s'", line); 
    14041415 
    1405             /* 
     1416/* 
    14061417             * TODO: get encoding out of this line too if 
    14071418             * present. example:   text/xml; charset=ISO-8859-1 
    1408              */ 
     1419*/ 
    14091420 
    14101421            if (info->mime != NULL) 
     
    14311442        } 
    14321443 
    1433         /* 
     1444/* 
    14341445         * TODO update mode is a vers2 btree feature. still unclear if 
    14351446         * we'll actually support it 
    1436          */ 
     1447*/ 
    14371448        if (!xmlStrncasecmp(line, (const xmlChar *)"Update-Mode", 11)) { 
    14381449 
     
    14501461        } 
    14511462 
    1452         /* 
     1463/* 
    14531464         * if we get here, unrecognized header line  
    1454          */ 
     1465*/ 
    14551466        SWISH_WARN("Unknown header line: '%s'\n", line); 
    14561467 
     
    14701481{ 
    14711482 
    1472     /* 
     1483/* 
    14731484     * init the global env vars, but don't override if already set  
    1474      */ 
     1485*/ 
    14751486 
    14761487    setenv("SWISH_PARSER_WARNINGS", "0", 0); 
     
    15121523        xmlBufferCreateSize((SWISH_MAX_HEADERS * SWISH_MAXSTRLEN) + SWISH_MAX_HEADERS); 
    15131524 
    1514     /* 
     1525/* 
    15151526     * based on extprog.c  
    1516      */ 
     1527*/ 
    15171528    while (fgets((char *)ln, SWISH_MAXSTRLEN, fh) != 0) { 
    15181529 
    1519         /* 
     1530/* 
    15201531         * we don't use fgetws() because we don't care about * indiv 
    15211532         * characters yet  
    1522          */ 
     1533*/ 
    15231534 
    15241535        xmlChar *end; 
     
    15281539        end = (xmlChar *)strrchr((char *)line, '\n'); 
    15291540 
    1530         /* 
     1541/* 
    15311542         * trim any white space at end of doc, including \n  
    1532          */ 
     1543*/ 
    15331544        if (end) { 
    15341545            while (end > line && isspace((int)*(end - 1))) 
     
    15401551        if (nheaders >= min_headers && xmlStrlen(line) == 0) { 
    15411552 
    1542             /* 
     1553/* 
    15431554             * blank line indicates body  
    1544              */ 
     1555*/ 
    15451556            curTime = swish_time_elapsed(); 
    15461557            parser_data = init_parser_data(s3); 
     
    15551566            read_buffer = swish_slurp_fh(fh, parser_data->docinfo->size); 
    15561567 
    1557             /* 
     1568/* 
    15581569             * parse  
    1559              */ 
     1570*/ 
    15601571            xmlErr = 
    15611572                docparser(parser_data, NULL, read_buffer, parser_data->docinfo->size); 
     
    15751586                SWISH_DEBUG_MSG("passing to handler"); 
    15761587 
    1577             /* 
     1588/* 
    15781589             * pass to callback function  
    1579              */ 
     1590*/ 
    15801591            (*s3->parser->handler) (parser_data); 
    15811592 
     
    15831594                SWISH_DEBUG_MSG("handler done"); 
    15841595 
    1585             /* 
     1596/* 
    15861597             * reset everything for next time  
    1587              */ 
     1598*/ 
    15881599 
    15891600            swish_xfree(read_buffer); 
     
    15931604            nheaders = 0; 
    15941605 
    1595             /* 
     1606/* 
    15961607             * count the file  
    1597              */ 
     1608*/ 
    15981609            file_cnt++; 
    15991610 
     
    16041615            } 
    16051616 
    1606             /* 
     1617/* 
    16071618             * timer  
    1608              */ 
     1619*/ 
    16091620            curTime = swish_time_elapsed(); 
    16101621 
     
    16211632        else { 
    16221633 
    1623             /* 
     1634/* 
    16241635             * we are reading headers  
    1625              */ 
     1636*/ 
    16261637            if (xmlBufferAdd(head_buf, line, -1)) 
    16271638                SWISH_CROAK("error adding header to buffer"); 
     
    16611672/*  
    16621673 * PUBLIC  
    1663  */ 
     1674*/ 
    16641675 
    16651676/*  
    16661677 * pass in a string including headers. like parsing fh, but only for one 
    16671678 * doc 
    1668  */ 
     1679*/ 
    16691680int 
    16701681swish_parse_buffer( 
     
    16891700    swish_check_docinfo(parser_data->docinfo, s3->config); 
    16901701 
    1691     /* 
     1702/* 
    16921703     * reposition buf pointer at start of body (just past head)  
    1693      */ 
     1704*/ 
    16941705 
    16951706    buf += head->body_start; 
     
    16971708    res = docparser(parser_data, 0, buf, xmlStrlen(buf)); 
    16981709 
    1699     /* 
     1710/* 
    17001711     * pass to callback function  
    1701      */ 
     1712*/ 
    17021713    (*s3->parser->handler) (parser_data); 
    17031714 
     
    17091720    } 
    17101721 
    1711     /* 
     1722/* 
    17121723     * free buffers  
    1713      */ 
     1724*/ 
    17141725    free_head(head); 
    17151726    free_parser_data(parser_data); 
     
    17281739/*  
    17291740 * PUBLIC  
    1730  */ 
     1741*/ 
    17311742int 
    17321743swish_parse_file( 
     
    17521763    res = docparser(parser_data, filename, 0, 0); 
    17531764 
    1754     /* 
     1765/* 
    17551766     * pass to callback function  
    1756      */ 
     1767*/ 
    17571768    (*s3->parser->handler) (parser_data); 
    17581769 
     
    17641775    } 
    17651776 
    1766     /* 
     1777/* 
    17671778     * free buffers  
    1768      */ 
     1779*/ 
    17691780    free_parser_data(parser_data); 
    17701781 
     
    18051816    ctxt->sax2 = 1; 
    18061817 
    1807     /* 
     1818/* 
    18081819     * always use sax2 -- this pulled from xmlDetextSAX2()  
    1809      */ 
     1820*/ 
    18101821    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); 
    18111822    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); 
     
    18141825        || (ctxt->str_xml_ns == NULL)) { 
    18151826 
    1816         /* 
     1827/* 
    18171828         * xmlErrMemory is/was not a public func but is in 
    18181829         * parserInternals.h * basically, this is a bad, fatal error, so 
    18191830         * we'll just die  
    1820          */ 
    1821  
    1822         /* 
     1831*/ 
     1832 
     1833/* 
    18231834         * xmlErrMemory(ctxt, NULL);  
    1824          */ 
     1835*/ 
    18251836        SWISH_CROAK("Fatal libxml2 memory error"); 
    18261837    } 
     
    19131924    enc = (xmlChar *)getenv("SWISH_ENCODING"); 
    19141925 
    1915     /* 
     1926/* 
    19161927     * TODO better encoding detection. for now we assume unknown text 
    19171928     * files are latin1  
    1918      */ 
     1929*/ 
    19191930    set_encoding(parser_data, buffer); 
    19201931 
     
    19581969    } 
    19591970 
    1960     /* 
     1971/* 
    19611972     * we obviously haven't any tags on which to trigger our metanames, 
    19621973     * so set default 
    19631974     * TODO get title somehow? 
    19641975     * TODO check config to determine if we should buffer swish_prop_description etc 
    1965      */ 
     1976*/ 
    19661977 
    19671978    push_tag_stack(parser_data->metastack, (xmlChar *)SWISH_DEFAULT_METANAME, 
     
    19922003{ 
    19932004 
    1994     /* 
     2005/* 
    19952006     * this feels like it doesn't work ... would iconv() be better ?  
    1996      */ 
     2007*/ 
    19972008 
    19982009    swish_xfree(parser_data->docinfo->encoding); 
     
    20222033    else { 
    20232034 
    2024         /*