Changeset 2097

Show
Ignore:
Timestamp:
03/23/08 23:49:06 (2 months ago)
Author:
karpet
Message:

write header

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libswish3/trunk/perl/docmaker.pl

    r1955 r2097  
    1010 
    1111die $usage unless @ARGV; 
     12 
     13my $docmaker = SWISH::Prog::Headers->new; 
    1214 
    1315#$ENV{SWISH3} = 1; 
     
    8385); 
    8486 
    85     my $header = SWISH::Prog::Headers->head( 
     87    my $header = $docmaker->head( 
    8688        $xml, 
    8789        {   url   => $i, 
     
    9698 
    9799} 
     100 
     101warn "\n"; 
     102 
  • libswish3/trunk/src/example/swish.xml

    r2046 r2097  
    66   <foo bias="+10" /> 
    77   <bar bias="-5" /> 
    8    <swishtitle bias="+50" alias="title" /> 
     8   <title bias="+50" alias_for="swishtitle" /> 
    99   <other>color size weight</other> 
    1010  </MetaNames> 
     
    1515   <lastmod type="date" /> 
    1616   <bing ignore_case="0" /> 
    17    <description verbatim="1" max="10000" alias="body" /> 
     17   <description verbatim="1" max="10000" alias_for="swishdescription" /> 
    1818   <notsorted sort="0" /> 
    1919   <myaliased>somealias someotheralias</myaliased> 
     20   <UPPERCASE alias_for="MiXeDCaSE" /> 
     21   <mixedcase type="text" /> 
    2022  </PropertyNames> 
     23 
     24  <MIME> 
     25   <au>foo/bar</au> 
     26  </MIME> 
    2127   
     28  <Parsers> 
     29   <XML>text/foo</XML> 
     30   <HTML>foo/bar 1234/5678</HTML> 
     31   <TXT>text/flop default</TXT> 
     32  </Parsers> 
     33 
    2234  <Tokenize>1</Tokenize> 
    2335</swish> 
  • libswish3/trunk/src/libswish3/config.c

    r2096 r2097  
    128128    config->stash       = NULL; 
    129129     
     130    /* misc default flags */ 
     131    config->flags->tokenize = 1; 
     132     
    130133    return config; 
    131134 
     
    235238            swish_xstrdup((xmlChar *) SWISH_PROP_DESCRIPTION)); 
    236239 
    237     /* misc default flags */ 
    238     config->flags->tokenize = 1; 
    239240     
    240241    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     
    399400 
    400401    /* values in config2 override and are set in config1 */ 
    401     //SWISH_DEBUG_MSG("merge properties"); 
     402    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     403        SWISH_DEBUG_MSG("merge properties"); 
     404    } 
    402405    merge_properties(config1->properties,   config2->properties); 
    403     //SWISH_DEBUG_MSG("merge metanames"); 
     406     
     407    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     408        SWISH_DEBUG_MSG("merge metanames"); 
     409    } 
    404410    merge_metanames(config1->metanames,     config2->metanames); 
    405     //SWISH_DEBUG_MSG("merge parsers"); 
     411     
     412    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     413        SWISH_DEBUG_MSG("merge parsers"); 
     414    } 
    406415    swish_hash_merge(config1->parsers,      config2->parsers); 
    407     //SWISH_DEBUG_MSG("merge mimes"); 
     416     
     417    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     418        SWISH_DEBUG_MSG("merge mimes"); 
     419    } 
    408420    swish_hash_merge(config1->mimes,        config2->mimes); 
    409     //SWISH_DEBUG_MSG("merge index"); 
     421     
     422    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     423        SWISH_DEBUG_MSG("merge index"); 
     424    } 
    410425    swish_hash_merge(config1->index,        config2->index); 
    411     //SWISH_DEBUG_MSG("merge tag_aliases"); 
     426     
     427    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     428        SWISH_DEBUG_MSG("merge tag_aliases"); 
     429    } 
    412430    swish_hash_merge(config1->tag_aliases,  config2->tag_aliases); 
    413     //SWISH_DEBUG_MSG("merge misc"); 
     431     
     432    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     433        SWISH_DEBUG_MSG("merge misc"); 
     434    } 
    414435    swish_hash_merge(config1->misc,         config2->misc); 
     436     
     437    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     438        SWISH_DEBUG_MSG("merge complete"); 
     439    } 
    415440 
    416441    /* set flags */ 
    417442    config1->flags->tokenize = config2->flags->tokenize; 
    418443     
    419 
    420  
     444    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     445        SWISH_DEBUG_MSG("flags set"); 
     446    } 
     447     
     448
     449 
  • libswish3/trunk/src/libswish3/hash.c

    r2096 r2097  
    9595 
    9696static void 
    97 merge_hashes( xmlHashTablePtr hash1, xmlChar *value, xmlChar *key ) 
     97merge_hashes( xmlChar *value, xmlHashTablePtr hash1, xmlChar *key ) 
    9898{ 
    9999    if (swish_hash_exists(hash1, key)) { 
    100         swish_hash_replace(hash1, key, value); 
     100        swish_hash_replace(hash1, key, swish_xstrdup(value)); 
    101101    } 
    102102    else { 
    103         swish_hash_add(hash1, key, value); 
     103        swish_hash_add(hash1, key, swish_xstrdup(value)); 
    104104    } 
    105105} 
  • libswish3/trunk/src/libswish3/header.c

    r2096 r2097  
    2121 
    2222#include <libxml/xmlreader.h> 
     23#include <libxml/xmlwriter.h> 
     24#include <libxml/encoding.h> 
    2325#include "libswish3.h" 
    2426 
     
    4042} headmaker; 
    4143 
    42 static void 
    43 do_index(xmlTextReaderPtr reader, headmaker *h) 
    44 
    45     SWISH_DEBUG_MSG("TODO index"); 
    46 
    47  
    48 static void 
    49 do_parser(xmlTextReaderPtr reader, headmaker *h) 
    50 
    51     SWISH_DEBUG_MSG("TODO parser"); 
    52 
    53  
    54 static void 
    55 do_alias(xmlTextReaderPtr reader, headmaker *h) 
    56 
    57     SWISH_DEBUG_MSG("TODO alias"); 
    58 
    59  
    60 static void 
    61 do_mime(xmlTextReaderPtr reader, headmaker *h) 
    62 
    63     SWISH_DEBUG_MSG("TODO mime"); 
    64 
    65  
    66 static void 
    67 do_metaname_aliases( 
     44typedef struct { 
     45    void*       thing1; 
     46    void*       thing2; 
     47    void*       thing3; 
     48} things; 
     49 
     50boolean 
     51swish_validate_header(char *filename); 
     52boolean 
     53swish_merge_config_with_header(char *filename, swish_Config *c); 
     54swish_Config * 
     55swish_read_header(char *filename); 
     56void 
     57swish_write_header(char* uri, swish_Config* config); 
     58static void 
     59read_metaname_aliases( 
     60    xmlChar *str, 
     61    headmaker *h, 
     62    swish_MetaName *meta 
     63); 
     64static void 
     65read_metaname_attr( 
     66    const xmlChar *attr,  
     67    const xmlChar *attr_val,  
     68    swish_MetaName *meta, 
     69    headmaker *h 
     70); 
     71static void 
     72read_metaname(xmlTextReaderPtr reader, headmaker *h); 
     73static void 
     74read_property_aliases( 
     75    xmlChar *str, 
     76    headmaker *h, 
     77    swish_Property *prop 
     78); 
     79static void 
     80read_property_attr( 
     81    const xmlChar *attr,  
     82    const xmlChar *attr_val,  
     83    swish_Property *prop, 
     84    headmaker *h 
     85); 
     86static void 
     87read_property(xmlTextReaderPtr reader, headmaker *h); 
     88static void 
     89process_node(xmlTextReaderPtr reader, headmaker *h); 
     90static void 
     91read_header(char *filename, headmaker *h); 
     92static void 
     93read_key_value_pair(xmlTextReaderPtr reader, xmlHashTablePtr hash, xmlChar* name); 
     94static void 
     95read_key_values_pair(xmlTextReaderPtr reader, xmlHashTablePtr hash, xmlChar* name); 
     96static headmaker * 
     97init_headmaker(); 
     98static void 
     99write_open_tag(xmlTextWriterPtr writer, xmlChar* tag); 
     100static void 
     101write_close_tag(xmlTextWriterPtr writer); 
     102static void 
     103write_element_with_content(xmlTextWriterPtr writer, xmlChar* tag, xmlChar* content); 
     104static void 
     105write_metanames(xmlTextWriterPtr writer, xmlHashTablePtr metanames); 
     106static void 
     107write_hash_entry(xmlChar* value, xmlTextWriterPtr writer, xmlChar* key); 
     108static void 
     109write_properties(xmlTextWriterPtr writer, xmlHashTablePtr properties); 
     110static void 
     111write_parsers(xmlTextWriterPtr writer, xmlHashTablePtr parsers); 
     112static void 
     113write_mimes(xmlTextWriterPtr writer, xmlHashTablePtr mimes); 
     114static void 
     115write_index(xmlTextWriterPtr writer, xmlHashTablePtr index); 
     116static void 
     117write_tag_aliases(xmlTextWriterPtr writer, xmlHashTablePtr tag_aliases); 
     118static void 
     119write_misc(xmlTextWriterPtr writer, xmlHashTablePtr hash); 
     120 
     121 
     122static void 
     123read_metaname_aliases( 
    68124    xmlChar *str, 
    69125    headmaker *h, 
     
    76132    strlist = swish_make_stringlist(str); 
    77133 
    78     /* loop over each alias and create a Property for each, 
    79        setting alias_for to prop->name 
     134    /* loop over each alias and create a MetaName for each, 
     135       setting alias_for to meta->name 
    80136    */ 
    81137    for (i=0; i < strlist->n; i++) { 
     
    114170 
    115171static void 
    116 do_metaname_attr( 
     172read_metaname_attr( 
    117173    const xmlChar *attr,  
    118174    const xmlChar *attr_val,  
     
    121177) 
    122178{ 
    123  
    124179    if (xmlStrEqual(attr, (xmlChar*)"bias")) { 
    125180        meta->bias = (boolean)strtol((char*)attr_val, (char**)NULL, 10); 
     
    128183        meta->id   = (int)strtol((char*)attr_val, (char**)NULL, 10); 
    129184    } 
    130     else if (xmlStrEqual(attr, (xmlChar*)"alias")) { 
    131         do_metaname_aliases( (xmlChar*)attr_val, h, meta ); 
     185    else if (xmlStrEqual(attr, (xmlChar*)"alias_for")) { 
     186        meta->alias_for = swish_str_tolower( BAD_CAST attr_val ); 
    132187    } 
    133188    else { 
     
    137192 
    138193static void 
    139 do_metaname(xmlTextReaderPtr reader, headmaker *h)  
     194read_metaname(xmlTextReaderPtr reader, headmaker *h)  
    140195{ 
    141196    xmlChar *value; 
     
    149204        &&  xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT ) { 
    150205        meta->name = swish_str_tolower( (xmlChar*)h->parent_name ); 
    151         do_metaname_aliases( xmlTextReaderValue(reader), h, meta ); 
     206        read_metaname_aliases( xmlTextReaderValue(reader), h, meta ); 
    152207        return; 
    153208    } 
     
    157212     
    158213        xmlTextReaderMoveToFirstAttribute(reader); 
    159         do_metaname_attr( 
     214        read_metaname_attr( 
    160215                xmlTextReaderConstName(reader), 
    161216                xmlTextReaderConstValue(reader), 
     
    165220         
    166221        while(xmlTextReaderMoveToNextAttribute(reader) == 1) { 
    167             do_metaname_attr( 
     222            read_metaname_attr( 
    168223                xmlTextReaderConstName(reader), 
    169224                xmlTextReaderConstValue(reader), 
     
    185240    }  
    186241    else { 
    187         SWISH_WARN("MetaName %s is already defined", meta->name); // TODO could be alias. how to check? 
     242        SWISH_WARN("MetaName %s is already defined", meta->name);  
     243        // TODO could be alias. how to check? 
    188244    } 
    189245     
     
    201257 
    202258static void 
    203 do_property_aliases( 
     259read_property_aliases( 
    204260    xmlChar *str, 
    205261    headmaker *h, 
     
    238294 
    239295static void 
    240 do_property_attr( 
     296read_property_attr( 
    241297    const xmlChar *attr,  
    242298    const xmlChar *attr_val,  
     
    272328        } 
    273329    } 
    274     else if (xmlStrEqual(attr, (xmlChar*)"alias")) { 
    275         do_property_aliases( (xmlChar*)attr_val, h, prop ); 
     330    else if (xmlStrEqual(attr, (xmlChar*)"alias_for")) { 
     331        prop->alias_for = swish_str_tolower(BAD_CAST attr_val); 
    276332    } 
    277333    else { 
     
    282338 
    283339static void 
    284 do_property(xmlTextReaderPtr reader, headmaker *h)  
     340read_property(xmlTextReaderPtr reader, headmaker *h)  
    285341{ 
    286342    xmlChar *value; 
     
    294350        &&  xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT ) { 
    295351        prop->name = swish_str_tolower( (xmlChar*)h->parent_name ); 
    296         do_property_aliases( xmlTextReaderValue(reader), h, prop ); 
     352        read_property_aliases( xmlTextReaderValue(reader), h, prop ); 
    297353        return; 
    298354    } 
     
    302358     
    303359        xmlTextReaderMoveToFirstAttribute(reader); 
    304         do_property_attr( 
     360        read_property_attr( 
    305361                xmlTextReaderConstName(reader), 
    306362                xmlTextReaderConstValue(reader), 
     
    310366         
    311367        while(xmlTextReaderMoveToNextAttribute(reader) == 1) { 
    312             do_property_attr( 
     368            read_property_attr( 
    313369                xmlTextReaderConstName(reader), 
    314370                xmlTextReaderConstValue(reader), 
     
    359415        return; 
    360416         
    361     if (xmlStrEqual(name, (const xmlChar*)"swish")) { 
     417    if (xmlStrEqual(name, (const xmlChar*)SWISH_HEADER_ROOT)) { 
    362418        h->is_valid = 1; 
    363419        return; 
     
    434490     
    435491        if (h->isprops) { 
    436             do_property(reader, h); 
     492            read_property(reader, h); 
    437493            return; 
    438494        } 
    439495        else if (h->ismetas) { 
    440             do_metaname(reader, h); 
     496            read_metaname(reader, h); 
    441497            return; 
    442498        } 
    443499        else if (h->isindex) { 
    444             do_index(reader, h); 
     500            read_key_value_pair(reader, h->config->index, (xmlChar*)name); 
    445501            return; 
    446502        }     
    447503        else if (h->isparser) { 
    448             do_parser(reader, h); 
     504            read_key_values_pair(reader, h->config->parsers, (xmlChar*)name); 
    449505            return; 
    450506        }     
    451507        else if (h->ismime) { 
    452             do_mime(reader, h); 
     508            read_key_value_pair(reader, h->config->mimes, (xmlChar*)name); 
    453509            return; 
    454510        }     
    455511        else if (h->isalias) { 
    456             do_alias(reader, h); 
     512            read_key_values_pair(reader, h->config->tag_aliases, (xmlChar*)name); 
    457513            return; 
    458514        }     
    459515        else if (type == XML_READER_TYPE_ELEMENT) { 
    460          
    461             //SWISH_DEBUG_MSG("misc header value"); 
     516            read_key_value_pair(reader, h->config->misc, (xmlChar*)name); 
     517            return; 
     518        } 
     519           
     520    } 
     521     
     522 
     523
     524 
     525static void 
     526read_key_values_pair(xmlTextReaderPtr reader, xmlHashTablePtr hash, xmlChar* name) 
     527
     528    swish_StringList* strlist; 
     529    xmlChar* str; 
     530    const xmlChar* value; 
     531    int i; 
     532     
     533    /* element. get text and add to misc */ 
     534    if (xmlTextReaderRead(reader) == 1) { 
     535        if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) { 
    462536             
    463             /* element. get text and add to misc */ 
    464             if (xmlTextReaderRead(reader) == 1) { 
    465                 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) { 
    466                     value = xmlTextReaderConstValue(reader); 
    467                     if (swish_hash_exists(h->config->misc, (xmlChar*)name)) { 
    468                         swish_hash_replace(h->config->misc, (xmlChar*)name, swish_xstrdup(value)); 
    469                     } 
    470                     else { 
    471                         swish_hash_add(h->config->misc, (xmlChar*)name, swish_xstrdup(value)); 
    472                     } 
     537            value = xmlTextReaderConstValue(reader); 
     538            str = swish_str_tolower( (xmlChar*)value ); 
     539            strlist = swish_make_stringlist( str ); 
     540             
     541            for(i=0; i<strlist->n; i++) { 
     542                //SWISH_DEBUG_MSG("key_values pair: %s -> %s", strlist->word[i], name); 
     543                if (swish_hash_exists(hash, strlist->word[i])) { 
     544                    swish_hash_replace(hash, strlist->word[i], swish_xstrdup( name )); 
    473545                } 
    474546                else { 
    475                     SWISH_CROAK("header line missing value: %s", name); 
     547                    swish_hash_add(hash, strlist->word[i], swish_xstrdup( name )); 
    476548                } 
    477549            } 
     550             
     551            swish_free_stringlist( strlist ); 
     552            swish_xfree( str ); 
     553             
     554        } 
     555        else { 
     556            SWISH_CROAK("header line missing value: %s", name); 
     557        } 
     558    } 
     559    else { 
     560        SWISH_CROAK("error reading value for header element %s", name); 
     561    } 
     562     
     563} 
     564 
     565static void 
     566read_key_value_pair(xmlTextReaderPtr reader, xmlHashTablePtr hash, xmlChar* name) 
     567{ 
     568    const xmlChar* value; 
     569     
     570    /* element. get text and add to misc */ 
     571    if (xmlTextReaderRead(reader) == 1) { 
     572        if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) { 
     573            value = xmlTextReaderConstValue(reader); 
     574            //SWISH_DEBUG_MSG("read key %s for value %s", name, value); 
     575            if (swish_hash_exists(hash, name)) { 
     576                swish_hash_replace(hash, name, swish_xstrdup(value)); 
     577            } 
    478578            else { 
    479                 SWISH_CROAK("error reading value for header element %s", name); 
     579                swish_hash_add(hash, name, swish_xstrdup(value)); 
    480580            } 
    481              
    482         }    
    483          
    484     } 
    485      
    486  
    487 
    488  
     581        } 
     582        else { 
     583            SWISH_CROAK("header line missing value: %s", name); 
     584        } 
     585    } 
     586    else { 
     587        SWISH_CROAK("error reading value for header element %s", name); 
     588    } 
     589     
     590
    489591 
    490592static void 
     
    506608                    0); 
    507609                     
    508         //SWISH_DEBUG_MSG("header parsed in-memory"); 
     610        if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     611            SWISH_DEBUG_MSG("header parsed in-memory"); 
     612        } 
    509613    } 
    510614    else { 
    511615        reader = xmlReaderForFile(filename, NULL, 0); 
    512616         
    513         //SWISH_DEBUG_MSG("header parsed from file"); 
     617        if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     618            SWISH_DEBUG_MSG("header parsed from file"); 
     619        } 
    514620    } 
    515621     
     
    534640} 
    535641 
     642static void 
     643test_meta_alias_for(swish_MetaName* meta, swish_Config* c, xmlChar* name) 
     644{ 
     645    if (    meta->alias_for != NULL 
     646        && !swish_hash_exists( c->metanames, meta->alias_for )  
     647    ) { 
     648        SWISH_CROAK("MetaName %s has alias_for value of %s but no such MetaName defined", 
     649            name, meta->alias_for); 
     650    } 
     651} 
     652 
     653static void 
     654test_prop_alias_for(swish_Property* prop, swish_Config* c, xmlChar* name) 
     655{ 
     656    if (    prop->alias_for != NULL 
     657        && !swish_hash_exists( c->properties, prop->alias_for )  
     658    ) { 
     659        SWISH_CROAK("Property %s has alias_for value of %s but no such Property defined", 
     660            name, prop->alias_for); 
     661    } 
     662} 
     663 
     664 
     665void 
     666swish_config_test_alias_fors(swish_Config* c) 
     667{ 
     668    xmlHashScan(c->metanames, (xmlHashScanner)test_meta_alias_for, c); 
     669    xmlHashScan(c->properties, (xmlHashScanner)test_prop_alias_for, c); 
     670} 
     671 
    536672static headmaker * 
    537673init_headmaker() 
     
    540676    h           = swish_xmalloc(sizeof(headmaker)); 
    541677    h->config   = swish_init_config(); 
     678    // mimes is set to NULL in default config but we need it to be a hash here. 
     679    h->config->mimes = swish_init_hash(8); 
    542680    h->isprops  = 0; 
    543681    h->ismetas  = 0; 
     
    566704    h = init_headmaker(); 
    567705    read_header( filename, h ); 
     706    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     707        SWISH_DEBUG_MSG("read_header complete"); 
     708    } 
    568709    swish_config_merge( c, h->config ); 
     710    if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     711        SWISH_DEBUG_MSG("config_merge complete"); 
     712    } 
    569713    swish_free_config( h->config ); 
    570714    swish_xfree( h ); 
     715     
     716    // now test that all the alias_for links resolve ok 
     717    swish_config_test_alias_fors(c); 
     718     
    571719    return 1; 
    572720} 
     
    583731    return c; 
    584732} 
     733 
     734static void 
     735write_open_tag(xmlTextWriterPtr writer, xmlChar* tag) 
     736{ 
     737    int rc; 
     738    rc = xmlTextWriterStartElement(writer, tag);\ 
     739    if (rc < 0) { 
     740        SWISH_CROAK("Error writing elemtn %s", tag); 
     741    } 
     742} 
     743 
     744static void 
     745write_close_tag(xmlTextWriterPtr writer) 
     746{ 
     747    int rc; 
     748    rc = xmlTextWriterEndElement(writer); 
     749    if (rc < 0) { 
     750        SWISH_CROAK("Error at xmlTextWriterEndElement"); 
     751    } 
     752} 
     753 
     754static void 
     755write_element_with_content(xmlTextWriterPtr writer, xmlChar* tag, xmlChar* content) 
     756{ 
     757    int rc; 
     758    rc = xmlTextWriterWriteElement(writer, tag, content); 
     759    if (rc < 0) { 
     760        SWISH_CROAK("Error writing element %s with content %s", tag, content); 
     761    } 
     762} 
     763 
     764static void 
     765write_metaname(swish_MetaName* meta, xmlTextWriterPtr writer, xmlChar* name) 
     766{ 
     767    int rc; 
     768    boolean is_alias; 
     769    write_open_tag(writer, name); 
     770    if (meta->alias_for == NULL) { 
     771        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "alias_for", BAD_CAST ""); 
     772        is_alias = 0; 
     773    } 
     774    else { 
     775        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "alias_for", meta->alias_for); 
     776        is_alias = 1; 
     777    } 
     778    if (rc < 0) { 
     779        SWISH_CROAK("Error writing metaname alias_for attribute for %s", name); 
     780    } 
     781     
     782    if (!is_alias) { 
     783        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "bias", "%d", meta->bias); 
     784        if (rc < 0) { 
     785            SWISH_CROAK("Error writing metaname bias attribute for %s", name); 
     786        } 
     787         
     788    } 
     789     
     790    rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", meta->id); 
     791    if (rc < 0) { 
     792        SWISH_CROAK("Error writing metaname id attribute for %s", name); 
     793    } 
     794    write_close_tag(writer); 
     795} 
     796 
     797static void 
     798write_metanames(xmlTextWriterPtr writer, xmlHashTablePtr metanames) 
     799{ 
     800    xmlHashScan(metanames, (xmlHashScanner)write_metaname, writer); 
     801} 
     802 
     803static void 
     804write_hash_entry(xmlChar* value, xmlTextWriterPtr writer, xmlChar* key) 
     805{ 
     806    write_element_with_content(writer, key, value); 
     807} 
     808 
     809static void 
     810write_property(swish_Property* prop, xmlTextWriterPtr writer, xmlChar* name) 
     811{ 
     812    int rc; 
     813    boolean is_alias; 
     814    write_open_tag(writer, name); 
     815    if (prop->alias_for == NULL) { 
     816        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "alias_for", BAD_CAST ""); 
     817        is_alias = 0; 
     818    } 
     819    else { 
     820        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "alias_for", prop->alias_for); 
     821        is_alias = 1; 
     822    } 
     823    if (rc < 0) { 
     824        SWISH_CROAK("Error writing property alias_for attribute for %s", name); 
     825    } 
     826    rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", prop->id); 
     827    if (rc < 0) { 
     828        SWISH_CROAK("Error writing property id attribute for %s", name); 
     829    } 
     830 
     831    /* all other attrs are irrelevant if this is an alias */ 
     832    if (!is_alias) { 
     833        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "ignore_case", "%d", prop->ignore_case); 
     834        if (rc < 0) { 
     835            SWISH_CROAK("Error writing property ignore_case attribute for %s", name); 
     836        } 
     837        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "verbatim", "%d", prop->verbatim); 
     838        if (rc < 0) { 
     839            SWISH_CROAK("Error writing property verbatim attribute for %s", name); 
     840        } 
     841        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "type", "%d", prop->type); 
     842        if (rc < 0) { 
     843            SWISH_CROAK("Error writing property type attribute for %s", name); 
     844        } 
     845        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "max", "%d", prop->max); 
     846        if (rc < 0) { 
     847            SWISH_CROAK("Error writing property max attribute for %s", name); 
     848        } 
     849        rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "sort", "%d", prop->sort); 
     850        if (rc < 0) { 
     851            SWISH_CROAK("Error writing property sort attribute for %s", name); 
     852        } 
     853    } 
     854    write_close_tag(writer); 
     855} 
     856 
     857static void 
     858write_properties(xmlTextWriterPtr writer, xmlHashTablePtr properties) 
     859{ 
     860    xmlHashScan(properties, (xmlHashScanner)write_property, writer); 
     861} 
     862 
     863static void 
     864write_parser(xmlChar* val, xmlTextWriterPtr writer, xmlChar* key) 
     865{ 
     866    write_element_with_content(writer, val, key); 
     867} 
     868 
     869static void 
     870write_parsers(xmlTextWriterPtr writer, xmlHashTablePtr parsers) 
     871{ 
     872    xmlHashScan(parsers, (xmlHashScanner)write_parser, writer); 
     873} 
     874 
     875static void 
     876write_mime(xmlChar* type, things* things, xmlChar* ext) 
     877{ 
     878    if (   ! swish_hash_exists((xmlHashTablePtr)things->thing1, ext)  
     879        || ! xmlStrEqual(swish_hash_fetch((xmlHashTablePtr)things->thing1, ext), type) 
     880    ) { 
     881     
     882        if (SWISH_DEBUG & SWISH_DEBUG_CONFIG) { 
     883            SWISH_DEBUG_MSG("writing unique MIME %s => %s", ext, type); 
     884        } 
     885        write_element_with_content( (xmlTextWriterPtr)things->thing3, ext, type ); 
     886    } 
     887} 
     888 
     889static void 
     890write_mimes(xmlTextWriterPtr writer, xmlHashTablePtr mimes) 
     891{ 
     892    // only write what differs from the default 
     893    things* things; 
     894    things = swish_xmalloc(sizeof(things)); 
     895     
     896    things->thing1 = swish_mime_hash(); 
     897    things->thing2 = mimes; 
     898    things->thing3 = writer; 
     899    xmlHashScan(mimes, (xmlHashScanner)write_mime, things); 
     900} 
     901 
     902static void 
     903write_index(xmlTextWriterPtr writer, xmlHashTablePtr index) 
     904{ 
     905    xmlHashScan(index, (xmlHashScanner)write_hash_entry, writer); 
     906} 
     907 
     908static void 
     909write_tag_aliases(xmlTextWriterPtr writer, xmlHashTablePtr tag_aliases) 
     910{ 
     911    xmlHashScan(tag_aliases, (xmlHashScanner)write_hash_entry, writer); 
     912} 
     913 
     914static void 
     915write_misc(xmlTextWriterPtr writer, xmlHashTablePtr hash) 
     916{ 
     917    xmlHashScan(hash, (xmlHashScanner)write_hash_entry, writer); 
     918} 
     919 
     920 
     921void 
     922swish_write_header(char* uri, swish_Config* config) 
     923{ 
     924#if !defined(LIBXML_WRITER_ENABLED) || !defined(LIBXML_OUTPUT_ENABLED) 
     925    SWISH_CROAK("libxml2 writer not compiled in this version of libxml2"); 
     926#else 
     927    int rc; 
     928    xmlTextWriterPtr writer; 
     929 
     930    /* Create a new XmlWriter for uri, with no compression. */ 
     931    writer = xmlNewTextWriterFilename((const char*)uri, 0); 
     932    if (writer == NULL) { 
     933        SWISH_CROAK("Error creating the xml writer\n"); 
     934    } 
     935     
     936    /* set some basic formatting rules. these make it easier to debug headers */ 
     937    rc = xmlTextWriterSetIndent(writer, 1); 
     938    if (rc < 0) { 
     939        SWISH_CROAK("failed to set indent on XML writer"); 
     940    } 
     941 
     942    /* Start the document with the xml default for the version, 
     943     * encoding UTF-8 (default) and the default for the standalone 
     944     * declaration. */ 
     945    rc = xmlTextWriterStartDocument(writer, NULL, NULL, NULL); 
     946    if (rc < 0) { 
     947        SWISH_CROAK("Error at xmlTextWriterStartDocument\n"); 
     948    } 
     949 
     950    /* root element 
     951    NOTE the BAD_CAST macro is xml2 shortcut for (xmlChar*) 
     952    */ 
     953    write_open_tag(writer, BAD_CAST SWISH_HEADER_ROOT); 
     954 
     955    /* Write a comment indicating a computer wrote this file */ 
     956    rc = xmlTextWriterWriteComment(writer,  
     957        BAD_CAST "written by libswish3 - DO NOT EDIT"); 
     958    if (rc < 0) { 
     959        SWISH_CROAK("Error at xmlTextWriterWriteComment\n"); 
     960    } 
     961     
     962    write_element_with_content(writer, BAD_CAST "swish_verson", BAD_CAST SWISH_VERSION); 
     963    write_element_with_content(writer, BAD_CAST "swish_lib_version", BAD_CAST SWISH_LIB_VERSION); 
     964 
     965    /* write MetaNames */ 
     966    write_open_tag(writer, BAD_CAST SWISH_META); 
     967    write_metanames(writer, config->metanames); 
     968    write_close_tag(writer); 
     969 
     970    /* write PropertyNames */ 
     971    write_open_tag(writer, BAD_CAST SWISH_PROP); 
     972    write_properties(writer, config->properties); 
     973    write_close_tag(writer); 
     974     
     975    /* write Parsers */ 
     976    write_open_tag(writer, BAD_CAST SWISH_PARSERS); 
     977    write_parsers(writer, config->parsers); 
     978    write_close_tag(writer); 
     979         
     980    /* write MIMEs */ 
     981    write_open_tag(writer, BAD_CAST SWISH_MIME); 
     982    write_mimes(writer, config->mimes); 
     983    write_close_tag(writer); 
     984 
     985    /* write index */ 
     986    write_open_tag(writer, BAD_CAST SWISH_INDEX); 
     987    write_index(writer, config->index); 
     988    write_close_tag(writer); 
     989     
     990    write_open_tag(writer, BAD_CAST SWISH_ALIAS); 
     991    write_tag_aliases(writer, config->tag_aliases); 
     992    write_close_tag(writer); 
     993 
     994    /* misc tags have no parent */ 
     995    write_misc(writer, config->misc); 
     996     
     997     
     998    /* this function will close any open tags */ 
     999    rc = xmlTextWriterEndDocument(writer); 
     1000    if (rc < 0) { 
     1001        SWISH_CROAK("Error at xmlTextWriterEndDocument\n"); 
     1002    } 
     1003 
     1004    xmlFreeTextWriter(writer); 
     1005#endif 
     1006} 
     1007 
  • libswish3/trunk/src/libswish3/libswish3.h

    r2096 r2097  
    5050 
    5151/* default config hash key names */ 
     52#define SWISH_HEADER_ROOT           "swish" 
    5253#define SWISH_INCLUDE_FILE          "IncludeConfigFile" 
    5354#define SWISH_PROP                  "PropertyNames" 
     
    637638boolean         swish_merge_config_with_header(char *filename, swish_Config *c); 
    638639swish_Config *  swish_read_header(char *filename); 
     640void            swish_write_header(char* filename, swish_Config* config); 
    639641/* 
    640642=cut 
  • libswish3/trunk/src/libswish3/mime_types.c

    r2041 r2097  
    2424 
    2525#include <err.h> 
    26 #include <libxml/xmlstring.h> 
    27 #include <libxml/hash.h> 
    2826#include <stdlib.h> 
    2927#include <string.h> 
     
    3331extern int SWISH_DEBUG; 
    3432 
    35 static char * defMimes[] = { 
     33// should be total number of strings (NOT pairs!) below 
     34#define SWISH_MIME_TABLE_COUNT  304 
     35 
     36static char*  
     37SWISH_MIME_TABLE[] = { 
    3638"ai",        "application/postscript", 
    3739"aif",       "audio/x-aiff", 
     
    192194}; 
    193195 
    194 static int nMimes = 304; 
    195  
    196196/* create hash of file ext => mime type */ 
    197 /* PUBLIC */ 
    198  
    199 xmlHashTablePtr swish_mime_hash() 
     197xmlHashTablePtr  
     198swish_mime_hash() 
    200199{ 
    201200    int i; 
    202     xmlHashTablePtr mimes = xmlHashCreate( 200 )
    203      
    204      
    205     for(i=0; i <= nMimes; i+=2) 
     201    xmlHashTablePtr mimes
     202    mimes = xmlHashCreate( SWISH_MIME_TABLE_COUNT / 2 ); 
     203     
     204    for(i=0; i <= SWISH_MIME_TABLE_COUNT; i+=2) 
    206205    { 
    207206        swish_hash_add( mimes, 
    208                             (xmlChar*)defMimes[i],  
    209                             swish_xstrdup((xmlChar*)defMimes[i+1]) 
    210                             ); 
     207                        (xmlChar*)SWISH_MIME_TABLE[i],  
     208                        swish_xstrdup((xmlChar*)SWISH_MIME_TABLE[i+1]) 
     209                      ); 
    211210    } 
    212211     
     
    215214 
    216215 
    217 /* PUBLIC */ 
    218216/* retrieve mime type from hash */ 
    219 xmlChar * swish_get_mime_type( swish_Config * config, xmlChar * fileext ) 
     217xmlChar*  
     218swish_get_mime_type( swish_Config* config, xmlChar* fileext ) 
    220219{ 
    221220    xmlChar * mime; 
     
    224223    { 
    225224        SWISH_WARN("No MIME type known for '%s' -- using '%s'", fileext, SWISH_DEFAULT_MIME ); 
    226         mime = swish_xstrdup( (xmlChar *)SWISH_DEFAULT_MIME ); 
     225        mime = swish_xstrdup( (xmlChar*)SWISH_DEFAULT_MIME ); 
    227226    } 
    228227    return swish_xstrdup( mime ); 
    229228} 
    230229 
    231 /* PUBLIC */ 
    232230/* returns parser type (TXT, HTML, XML) based on mime type */ 
    233 xmlChar * swish_get_parser( swish_Config * config, xmlChar *mime ) 
     231xmlChar*  
     232swish_get_parser( swish_Config * config, xmlChar *mime ) 
    234233{ 
    235234    xmlChar *parser; 
  • libswish3/trunk/src/libswish3/property.c

    r2041 r2097  
    2525swish_init_property( xmlChar *name ) 
    2626{ 
    27     swish_Property *prop
    28     prop = swish_xmalloc(sizeof(swish_Property)); 
    29     prop->ref_cnt       = 0; 
    30     prop->id            = 0; 
    31     prop->name          = name; 
    32     prop->ignore_case   = 1; 
    33     prop->type          = SWISH_PROP_STRING; 
    34     prop->verbatim      = 0; 
    35     prop->alias_for     = NULL; 
    36     prop->max           = 0; 
    37     prop->sort          = 0; 
    38     return prop
     27    swish_Property *p
     28    p = swish_xmalloc(sizeof(swish_Property)); 
     29    p->ref_cnt       = 0; 
     30    p->id            = 0; 
     31    p->name          = name; 
     32    p->ignore_case   = 1; 
     33    p->type          = SWISH_PROP_STRING; 
     34    p->verbatim      = 0; 
     35    p->alias_for     = NULL; 
     36    p->max           = 0; 
     37    p->sort          = 0; 
     38    return p
    3939} 
    4040 
     
    4343{ 
    4444    SWISH_DEBUG_MSG("\n\ 
    45     prop->ref_cnt       = %d\n\ 
    46     prop->id            = %d\n\ 
    47     prop->name          = %s\n\ 
    48     prop->ignore_case   = %d\n\ 
    49     prop->type          = %d\n\ 
    50     prop->verbatim      = %d\n\ 
    51     prop->alias_for     = %s\n\ 
    52     prop->max           = %d\n\ 
    53     prop->sort          = %d\n\ 
     45    p->ref_cnt       = %d\n\ 
     46    p->id            = %d\n\ 
     47    p->name          = %s\n\ 
     48    p->ignore_case   = %d\n\ 
     49    p->type          = %d\n\ 
     50    p->verbatim      = %d\n\ 
     51    p->alias_for     = %s\n\ 
     52    p->max           = %d\n\ 
     53    p->sort          = %d\n\ 
    5454    ", p->ref_cnt, p->id, p->name, p->ignore_case, 
    5555    p->type, p->verbatim, p->alias_for, p->max, p->sort); 
  • libswish3/trunk/src/libswish3/string.c

    r2096 r2097  
    252