Changeset 2130

Show
Ignore:
Timestamp:
04/15/08 23:12:59 (1 month ago)
Author:
karpet
Message:

fix bug with XMLClassAttributes. all tests pass... for now.

Files:

Legend:

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

    r2123 r2130  
    316316{ 
    317317    xmlChar            *name; 
     318    xmlChar            *metaname; 
     319    xmlChar            *context; 
    318320    struct swish_Tag   *next; 
    319321    unsigned int        n; 
     
    326328    unsigned int       count; 
    327329    char              *name;       // debugging aid -- name of the stack 
    328     xmlChar           *flat;       // all the stack item names as a string for convenience 
    329330}; 
    330331 
     
    356357    xmlChar               *tag;                // current tag name 
    357358    swish_DocInfo         *docinfo;            // document-specific properties 
    358     unsigned int           no_index;           // toggle flag for special comments 
    359     unsigned int           is_html;            // shortcut flag for html parser 
    360     unsigned int           bump_word;          // boolean for moving word position/adding space 
     359    boolean                no_index;           // toggle flag for special comments 
     360    boolean                is_html;            // shortcut flag for html parser 
     361    boolean                bump_word;          // boolean for moving word position/adding space 
    361362    unsigned int           word_pos;           // word position in document 
    362363    unsigned int           offset;             // current offset position 
  • libswish3/trunk/src/libswish3/parser.c

    r2129 r2130  
    8484    swish_ParserData *parser_data 
    8585); 
    86 static swish_TagStack *push_tag_stack( 
     86static void push_tag_stack( 
     87    swish_TagStack *stack, 
     88    xmlChar *tag, 
     89    xmlChar *metaname 
     90); 
     91static swish_Tag *pop_tag_stack( 
     92    swish_TagStack *stack 
     93); 
     94static swish_Tag *pop_tag_stack_on_match( 
    8795    swish_TagStack *stack, 
    8896    xmlChar *tag 
    8997); 
    90 static int pop_tag_stack( 
    91     swish_TagStack *stack 
    92 ); 
    93 static xmlChar *pop_tag_stack_on_match( 
    94     swish_TagStack *stack, 
    95     xmlChar *tag 
     98static void free_swishTag( 
     99    swish_Tag * st 
    96100); 
    97101 
     
    292296        SWISH_DEBUG_MSG(" tag: %s (%s) ", tag, parser_data->tag); 
    293297        if (atts != NULL) { 
    294             SWISH_DEBUG_MSG(" has attributes [%d]", xmlStrlen((xmlChar*)atts)); 
    295             for (i = 0; (atts[i] != NULL); i+=2) { 
     298            SWISH_DEBUG_MSG(" has attributes [%d]", xmlStrlen((xmlChar *)atts)); 
     299            for (i = 0; (atts[i] != NULL); i += 2) { 
    296300                SWISH_DEBUG_MSG(" att: %s=", atts[i]); 
    297                 if (atts[i+1] != NULL) { 
    298                     SWISH_DEBUG_MSG(" '%s'", atts[i+1]); 
     301                if (atts[i + 1] != NULL) { 
     302                    SWISH_DEBUG_MSG(" '%s'", atts[i + 1]); 
    299303                } 
    300304            } 
     
    403407                swish_hash_fetch(parser_data->s3->config->stringlists, 
    404408                                 (xmlChar *)SWISH_CLASS_ATTRIBUTES); 
    405                                   
    406              
    407                                   
     409 
    408410            for (i = 0; (atts[i] != NULL); i += 2) { 
    409411 
     
    603605    if (nb_attributes > 0) { 
    604606        atts = swish_xmalloc(((nb_attributes * 2) + 1) * sizeof(xmlChar *)); 
    605         j=0; 
     607        j = 0; 
    606608        for (i = 0; i < nb_attributes * 5; i += 5) { 
    607609            atts[j] = (xmlChar *)attributes[i]; 
    608610            len = (int)(attributes[i + 4] - attributes[i + 3]); 
    609611            if (len > 0) { 
    610                 atts[j+1] = xmlStrsub(attributes[i + 3], 0, len); 
     612                atts[j + 1] = xmlStrsub(attributes[i + 3], 0, len); 
    611613            } 
    612614            else { 
    613615                atts[j] = NULL; 
    614616            } 
    615             j+=2; 
     617            j += 2; 
    616618        } 
    617619        atts[j] = NULL; 
    618620    } 
    619      
     621 
    620622    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    621623        SWISH_DEBUG_MSG(" tag: %s nb_attributes %d", localname, nb_attributes); 
    622624        if (atts != NULL) { 
    623             for (i = 0; (atts[i] != NULL); i+=2) { 
     625            for (i = 0; (atts[i] != NULL); i += 2) { 
    624626                SWISH_DEBUG_MSG(" att: %s=%s", atts[i], atts[i + 1]); 
    625627                //SWISH_DEBUG_MSG(" att: %s=", atts[i++], atts[i] || ""); 
     
    674676            SWISH_DEBUG_MSG(" %s = new property", parser_data->tag); 
    675677 
    676         add_stack_to_prop_buf(NULL, parser_data);       /* TODO why NULL * here ?? */ 
     678        add_stack_to_prop_buf(NULL, parser_data); /* NULL means all properties in the stack are added */ 
    677679        xmlBufferEmpty(parser_data->prop_buf); 
    678680 
    679         parser_data->propstack = push_tag_stack(parser_data->propstack, parser_data->tag); 
     681        push_tag_stack(parser_data->propstack, (xmlChar *)tag, parser_data->tag); 
    680682 
    681683        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
     
    691693 
    692694        flush_buffer(parser_data, parser_data->metastack->head->name, 
    693                      parser_data->metastack->flat); 
    694  
    695         parser_data->metastack = push_tag_stack(parser_data->metastack, parser_data->tag); 
     695                     parser_data->metastack->head->context); 
     696 
     697        push_tag_stack(parser_data->metastack, (xmlChar *)tag, parser_data->tag); 
    696698    } 
    697699 
     
    707709) 
    708710{ 
    709     xmlChar *context; 
    710711    swish_ParserData *parser_data; 
     712    swish_Tag *st; 
    711713 
    712714    parser_data = (swish_ParserData *)data; 
     
    724726        SWISH_DEBUG_MSG(" endElement(%s) (%s)", (xmlChar *)tag, parser_data->tag); 
    725727 
    726     if ((context = 
    727          pop_tag_stack_on_match(parser_data->propstack, parser_data->tag)) != NULL) { 
    728  
    729         /* 
    730          * SWISH_DEBUG_MSG("popped %s from propstack", context);  
    731          */ 
     728    if ((st = pop_tag_stack_on_match(parser_data->propstack, (xmlChar *)tag)) != NULL) { 
     729 
    732730        add_stack_to_prop_buf(parser_data->tag, parser_data); 
    733731        xmlBufferEmpty(parser_data->prop_buf); 
    734         swish_xfree(context); 
    735     } 
    736  
    737     if ((context = 
    738          pop_tag_stack_on_match(parser_data->metastack, parser_data->tag)) != NULL) { 
    739  
    740         /* 
    741          * SWISH_DEBUG_MSG("popped %s from metastack", parser_data->tag);  
    742          */ 
    743         flush_buffer(parser_data, parser_data->tag, context); 
    744         swish_xfree(context); 
     732        free_swishTag(st); 
     733    } 
     734 
     735    if ((st = pop_tag_stack_on_match(parser_data->metastack, (xmlChar *)tag)) != NULL) { 
     736 
     737        flush_buffer(parser_data, st->metaname, st->context); 
     738        free_swishTag(st); 
    745739    } 
    746740 
     
    10351029    ptr->metastack->head = NULL; 
    10361030    ptr->metastack->temp = NULL; 
    1037     ptr->metastack->flat = NULL; 
    10381031    ptr->metastack->count = 0; 
    1039     ptr->metastack = push_tag_stack(ptr->metastack, (xmlChar *)SWISH_DEFAULT_METANAME); 
     1032    push_tag_stack(ptr->metastack, (xmlChar *)SWISH_DEFAULT_METANAME, 
     1033                   (xmlChar *)SWISH_DEFAULT_METANAME); 
    10401034 
    10411035    ptr->propstack = (swish_TagStack *)swish_xmalloc(sizeof(swish_TagStack)); 
     
    10431037    ptr->propstack->head = NULL; 
    10441038    ptr->propstack->temp = NULL; 
    1045     ptr->propstack->flat = NULL; 
    10461039    ptr->propstack->count = 0; 
    1047     ptr->propstack = push_tag_stack(ptr->propstack, (xmlChar *)"_"); 
     1040    push_tag_stack(ptr->propstack, (xmlChar *)"_", (xmlChar *)"_"); 
    10481041 
    10491042    /* 
     
    10951088) 
    10961089{ 
     1090    swish_Tag *st; 
    10971091 
    10981092    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
     
    11071101     * Pop the stacks  
    11081102     */ 
    1109     while (pop_tag_stack(ptr->metastack)) { 
     1103    while ((st = pop_tag_stack(ptr->metastack)) != NULL) { 
    11101104        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    1111             SWISH_DEBUG_MSG("head of stack is %d %s", ptr->metastack->count, 
    1112                             ptr->metastack->head->name); 
    1113  
     1105            SWISH_DEBUG_MSG("%s %d POP %s [%s] [%s]", ptr->metastack->name, 
     1106                            ptr->metastack->count, st->name, st->metaname, st->context); 
     1107 
     1108        free_swishTag(st); 
    11141109    } 
    11151110 
     
    11191114    swish_xfree(ptr->metastack); 
    11201115 
    1121     while (pop_tag_stack(ptr->propstack)) { 
     1116    while ((st = pop_tag_stack(ptr->propstack)) != NULL) { 
    11221117        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    1123             SWISH_DEBUG_MSG("head of stack is %d %s", ptr->propstack->count, 
    1124                             ptr->propstack->head->name); 
    1125  
     1118            SWISH_DEBUG_MSG("%s %d POP %s [%s] [%s]", ptr->propstack->name, 
     1119                            ptr->propstack->count, st->name, st->metaname, st->context); 
     1120 
     1121        free_swishTag(st); 
    11261122    } 
    11271123 
     
    19621958     */ 
    19631959 
    1964     parser_data->metastack = push_tag_stack(parser_data->metastack, (xmlChar *) 
    1965                                             SWISH_DEFAULT_METANAME); 
     1960    push_tag_stack(parser_data->metastack, (xmlChar *)SWISH_DEFAULT_METANAME, 
     1961                   (xmlChar *)SWISH_DEFAULT_METANAME); 
    19661962 
    19671963    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    1968         SWISH_DEBUG_MSG("stack pushed for %s", parser_data->metastack->flat); 
     1964        SWISH_DEBUG_MSG("%s stack PUSH %s", parser_data->metastack->head->context); 
    19691965 
    19701966    buffer_characters(parser_data, buffer, size); 
     
    20462042 
    20472043    if (context == NULL) 
    2048         context = parser_data->metastack->flat; 
     2044        context = parser_data->metastack->head->context; 
    20492045 
    20502046    swish_WordList *tmplist; 
     
    21272123    int i = 0; 
    21282124 
    2129     SWISH_DEBUG_MSG("%s '%s' stack->count: %d", stack->name, stack->flat, stack->count); 
     2125    SWISH_DEBUG_MSG("%s stack->count: %d", stack->name, stack->count); 
    21302126 
    21312127    for (stack->temp = stack->head; stack->temp != NULL; stack->temp = stack->temp->next) { 
     
    21722168        size = ((xmlStrlen(flat) + (xmlStrlen(stack->temp->name)) * sizeof(xmlChar))) + 2; 
    21732169        tmp = swish_xmalloc(size); 
    2174         if (sprintf((char *)tmp, "%s %s", (char *)flat, (char *)stack->temp->name) > 0) { 
     2170        if (snprintf((char *)tmp, size, "%s %s", (char *)flat, (char *)stack->temp->name) > 0) { 
    21752171            if (flat != NULL) 
    21762172                swish_xfree(flat); 
     
    21932189) 
    21942190{ 
    2195     swish_TagStack *s
     2191    swish_TagStack *stack
    21962192    int cleanwsp; 
    21972193    swish_Property *prop; 
    21982194 
    2199     s = parser_data->propstack; 
     2195    stack = parser_data->propstack; 
    22002196    cleanwsp = 1; 
     2197     
     2198    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
     2199        SWISH_DEBUG_MSG("adding property %s to buffer", tag); 
     2200    } 
    22012201 
    22022202    if (tag != NULL) { 
     
    22092209            cleanwsp = 0; 
    22102210 
    2211         /* 
    2212          * SWISH_DEBUG_MSG(" add_stack_to_prop_buf: '%s'", 
    2213          * xmlBufferContent(parser_data->prop_buf));  
    2214          */ 
    2215  
    22162211        swish_add_buf_to_nb(parser_data->properties, tag, parser_data->prop_buf, 
    22172212                            (xmlChar *)SWISH_PROP_CONNECTOR, cleanwsp, 0); 
     
    22192214    } 
    22202215 
    2221     for (s->temp = s->head; s->temp != NULL; s->temp = s->temp->next) { 
    2222         if (xmlStrEqual(s->temp->name, (xmlChar *)"_")) /* top of * the * 
    2223                                                          * stack * * is * 
    2224                                                          * just a * * * 
    2225                                                          * placeholder */ 
     2216    // add for each member in the stack 
     2217    // TODO configurable?? 
     2218    for (stack->temp = stack->head; stack->temp != NULL; stack->temp = stack->temp->next) { 
     2219        if (xmlStrEqual(stack->temp->name, (xmlChar *)"_")) 
    22262220            continue; 
    22272221 
    2228         swish_add_buf_to_nb(parser_data->properties, s->temp->name, parser_data->prop_buf, 
     2222        swish_add_buf_to_nb(parser_data->properties, stack->temp->name, parser_data->prop_buf, 
    22292223                            (xmlChar *)SWISH_PROP_CONNECTOR, cleanwsp, 0); 
    22302224    } 
     
    22322226} 
    22332227 
    2234 static swish_TagStack * 
     2228static void 
     2229free_swishTag( 
     2230    swish_Tag * st 
     2231
     2232
     2233    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
     2234        SWISH_DEBUG_MSG(" freeing swishTag: %s %s %s", st->name, st->metaname, st->context); 
     2235    } 
     2236     
     2237    swish_xfree(st->name); 
     2238    swish_xfree(st->metaname); 
     2239    swish_xfree(st->context); 
     2240    swish_xfree(st); 
     2241
     2242 
     2243static void 
    22352244push_tag_stack( 
    22362245    swish_TagStack *stack, 
    2237     xmlChar *tag 
     2246    xmlChar *tag, 
     2247    xmlChar *metaname 
    22382248) 
    22392249{ 
     
    22422252 
    22432253    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2244         SWISH_DEBUG_MSG(" >>>>>>> before push: tag = '%s'", tag); 
     2254        SWISH_DEBUG_MSG("%s PUSH: tag = '%s'", stack->name, tag); 
    22452255        _debug_stack(stack); 
    2246  
    2247     } 
    2248  
    2249     /* 
    2250      * assign this tag to the struct  
    2251      */ 
     2256    } 
     2257 
     2258    //assign this tag to the struct  
    22522259    thistag->name = swish_xstrdup(tag); 
    22532260 
    2254     /* 
    2255      * increment counter  
    2256      */ 
     2261    // the metaname (the normalized tag) 
     2262    thistag->metaname = swish_xstrdup(metaname); 
     2263 
     2264    //increment counter  
    22572265    thistag->n = stack->count++; 
    22582266 
    2259     /* 
    2260      * add to stack  
    2261      */ 
     2267    // push 
    22622268    thistag->next = stack->head; 
    22632269    stack->head = thistag; 
    22642270 
    2265     /* 
    2266      * cache the flattened value  
    2267      */ 
    2268     if (stack->flat != NULL) 
    2269         swish_xfree(stack->flat); 
    2270  
    2271     stack->flat = flatten_tag_stack(NULL, stack); 
     2271    // create context 
     2272    thistag->context = flatten_tag_stack(NULL, stack); 
    22722273 
    22732274    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2274         SWISH_DEBUG_MSG(" >>> stack size: %d  thistag count: %d  current head tag = '%s'", 
    2275                         stack->count, thistag->n, stack->head->name); 
     2275        SWISH_DEBUG_MSG("%s size: %d  thistag count: %d  current head tag = '%s'", 
     2276                        stack->name, stack->count, thistag->n, stack->head->context); 
    22762277 
    22772278        _debug_stack(stack); 
     
    22792280    } 
    22802281 
    2281     return stack; 
    2282 
    2283  
    2284 static int 
     2282
     2283 
     2284static swish_Tag * 
    22852285pop_tag_stack( 
    22862286    swish_TagStack *stack 
    22872287) 
    22882288{ 
     2289    // stack is completely empty 
     2290    if (stack->head == NULL) 
     2291        return NULL; 
    22892292 
    22902293    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2291         SWISH_DEBUG_MSG(" pop_tag_stack: %s from %s", stack->head->name, stack->name); 
     2294        SWISH_DEBUG_MSG("%s POP: %s", stack->name, stack->head->name); 
    22922295        _debug_stack(stack); 
    22932296 
     
    22962299    if (stack->count > 1) { 
    22972300        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2298             SWISH_DEBUG_MSG("  >>>  %d: popping '%s' from tagstack <<<", stack->head->n, 
     2301            SWISH_DEBUG_MSG("%s %d: popping '%s'", stack->name, stack->head->n, 
    22992302                            stack->head->name); 
    23002303 
     
    23032306        stack->temp = stack->head; 
    23042307        stack->head = stack->head->next; 
    2305  
    2306         /* 
    2307          * free the memory for the popped meta  
    2308          */ 
    2309         swish_xfree(stack->temp->name); 
    2310         stack->temp->n = 0; 
    2311         swish_xfree(stack->temp); 
    2312  
    23132308        stack->count--; 
    23142309 
     
    23162311    else { 
    23172312 
     2313        // the stack has only one member 
     2314 
    23182315        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2319             SWISH_DEBUG_MSG 
    2320                 ("  >>>  %d: popping '%s' from tagstack will leave stack empty (flat: %s) <<<"
    2321                  stack->head->n, stack->head->name, stack->flat); 
     2316            SWISH_DEBUG_MSG("%s %d: popping '%s' will leave stack empty [%s]", 
     2317                            stack->name, stack->head->n, stack->head->name
     2318                            stack->head->context); 
    23222319 
    23232320        } 
     
    23252322        stack->temp = stack->head; 
    23262323        stack->head = NULL; 
    2327         swish_xfree(stack->flat); 
    2328         stack->flat = NULL; 
    2329  
    2330         swish_xfree(stack->temp->name); 
    2331         stack->temp->n = 0; 
    2332         swish_xfree(stack->temp); 
    23332324        stack->count--; 
    23342325 
    2335         return 0; 
    2336     } 
    2337  
    2338     /* 
    2339      * cache the flattened value  
    2340      */ 
    2341     if (stack->flat != NULL) 
    2342         swish_xfree(stack->flat); 
    2343  
    2344     stack->flat = flatten_tag_stack(NULL, stack); 
     2326    } 
    23452327 
    23462328    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2347         SWISH_DEBUG_MSG("  >> stack size = %d   head of stack = %s <<", stack->count, 
    2348                         stack->head->name); 
    2349         _debug_stack(stack); 
    2350     } 
    2351  
    2352     return stack->count; 
     2329        SWISH_DEBUG_MSG("%s stack count = %d", stack->name, stack->count); 
     2330    } 
     2331 
     2332    return stack->temp; 
    23532333 
    23542334} 
    23552335 
    23562336/*  
    2357  * returns previous ->flat if the current tag matches the top of the stack  
    2358  * and gets popped  
     2337 * returns top of the stack if the current tag matches. 
    23592338 */ 
    2360 static xmlChar
     2339static swish_Tag
    23612340pop_tag_stack_on_match( 
    23622341    swish_TagStack *stack, 
     
    23652344{ 
    23662345 
    2367     xmlChar *prev_flat; 
    2368  
    2369     prev_flat = swish_xstrdup(stack->flat)
     2346    swish_Tag *st; 
     2347 
     2348    st = NULL
    23702349 
    23712350    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2372         SWISH_DEBUG_MSG("pop_tag_stack_on_match() for %s", stack->name); 
    2373         SWISH_DEBUG_MSG("comparing '%s' against '%s'", tag, stack->head->name); 
     2351        SWISH_DEBUG_MSG("%s: POP if %s matches %s", stack->name, tag, stack->head->name); 
    23742352        _debug_stack(stack); 
    23752353    } 
     
    23782356 
    23792357        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2380             SWISH_DEBUG_MSG 
    2381                 (" >>>>>>>>>>>>>>>>>>>  current tag = '%s' matches top of tagstack", tag); 
     2358            SWISH_DEBUG_MSG("%s POP '%s' == head", stack->name, tag); 
    23822359 
    23832360        } 
     
    23862363         * more than default meta  
    23872364         */ 
    2388         if (pop_tag_stack(stack)) { 
     2365        if ((st = pop_tag_stack(stack)) != NULL) { 
    23892366 
    23902367            if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
    2391                 SWISH_DEBUG_MSG("stack popped. tag = %s   stack->head = %s", tag, 
    2392                                 stack->head->name); 
     2368                SWISH_DEBUG_MSG("%s POPPED.  tag = %s  st->name = %s", stack->name, 
     2369                                tag, st->name); 
     2370                 
    23932371                _debug_stack(stack); 
    23942372            } 
     
    23972375 
    23982376        /* 
    2399          * only tag on stack  
     2377         * only tag on stack. TODO do we ever get here?  
    24002378         */ 
    24012379        else if (stack->count) { 
    24022380            if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    2403                 SWISH_DEBUG_MSG("  using stack->head %s", stack->head->name); 
    2404  
    2405         } 
    2406  
    2407         return prev_flat; 
     2381                SWISH_DEBUG_MSG("%s head %s", stack->name, stack->head->name); 
     2382 
     2383        } 
     2384        else { 
     2385            SWISH_CROAK("%s stack was empty", stack->name); 
     2386        } 
     2387 
    24082388    } 
    24092389    else { 
     2390 
    24102391        if (SWISH_DEBUG & SWISH_DEBUG_PARSER) 
    2411             SWISH_DEBUG_MSG("no match for '%s'", tag); 
    2412  
    2413     } 
    2414  
    2415     swish_xfree(prev_flat); 
    2416  
    2417     return 0; 
    2418 
     2392            SWISH_DEBUG_MSG("%s: no match for '%s'", stack->name, tag); 
     2393 
     2394    } 
     2395     
     2396    if (SWISH_DEBUG & SWISH_DEBUG_PARSER) { 
     2397        if (st != NULL) 
     2398            SWISH_DEBUG_MSG("POP on match returning: %s", st->name); 
     2399        else 
     2400            SWISH_DEBUG_MSG("POP on match returning null"); 
     2401    } 
     2402 
     2403    return st; 
     2404
  • libswish3/trunk/src/t/004-metanames.t

    r2127 r2130  
    2727); 
    2828 
    29 like( $buf, qr!<swishtitle>mytitle here</swishtitle>!,       "swishtitle" ); 
    30 like( $buf, qr!<mytag1> substr: \s+ some text!s,             "mytag1" ); 
    31 like( $buf, qr!<mytag1> substr: \s+ yet again\s+and again!s, "mytag1 again" ); 
    32 like( $buf, qr!<mytag3.foo> substr: \s+ blah blah!s,         "mytag3.foo" ); 
    33 like( $buf, qr!<mytag3> substr: \s+ foo bar!s,               "mytag3" ); 
     29like( $buf, qr!<swishtitle>mytitle here</swishtitle>!,     "swishtitle" ); 
     30like( $buf, qr!<mytag1> substr:\s+some text!s,             "mytag1" ); 
     31like( $buf, qr!<mytag1> substr:\s+yet again\s+and again!s, "mytag1 again" ); 
     32like( $buf, qr!<mytag3.foo> substr:\s+blah blah!s,         "mytag3.foo" ); 
     33like( $buf, qr!<mytag3> substr:\s+foo bar!s,               "mytag3" );