Changeset 2046

Show
Ignore:
Timestamp:
03/07/08 22:33:11 (2 months ago)
Author:
karpet
Message:

more config refactoring

Files:

Legend:

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

    r2042 r2046  
    3939 
    4040static void     config_printer(xmlChar * val, xmlChar * str, xmlChar * key); 
    41  
    42 static xmlDocPtr parse_xml_config(xmlChar * conf); 
    43 static xmlChar *get_node_name(xmlNode * node); 
    44 static xmlNode *get_dom_root(xmlDocPtr doc); 
    45  
    4641static void     free_string(xmlChar *payload, xmlChar *key); 
    4742static void     free_props(swish_Property *prop, xmlChar *propname); 
     
    6560    } 
    6661    prop->ref_cnt--; 
    67     swish_free_property(prop); 
     62    if (prop->ref_cnt < 1) { 
     63        swish_free_property(prop); 
     64    } 
    6865} 
    6966 
     
    7673    } 
    7774    meta->ref_cnt--; 
    78     swish_free_metaname(meta); 
     75    if (meta->ref_cnt < 1) { 
     76        swish_free_metaname(meta); 
     77    } 
    7978} 
    8079 
     
    120119    config              = swish_xmalloc(sizeof(swish_Config)); 
    121120    config->flags       = swish_xmalloc(sizeof(swish_ConfigFlags)); 
    122     config->misc        = swish_new_hash(8); 
    123     config->metanames   = swish_new_hash(8); 
    124     config->properties  = swish_new_hash(8); 
    125     config->parsers     = swish_new_hash(8); 
    126     config->index       = swish_new_hash(8); 
    127     config->tag_aliases = swish_new_hash(8); 
     121    config->misc        = swish_init_hash(8); 
     122    config->metanames   = swish_init_hash(8); 
     123    config->properties  = swish_init_hash(8); 
     124    config->parsers     = swish_init_hash(8); 
     125    config->index       = swish_init_hash(8); 
     126    config->tag_aliases = swish_init_hash(8); 
    128127    config->mimes       = NULL; 
    129128    config->ref_cnt     = 0; 
     
    241240} 
    242241 
    243 /* PUBLIC */ 
    244 swish_Config  * 
    245 swish_add_config(xmlChar * conf, swish_Config * config) 
     242swish_Config * 
     243swish_add_config(xmlChar *conf, swish_Config *config) 
    246244{ 
    247245 
    248246    config = swish_parse_config(conf, config); 
    249  
    250247    if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    251248        swish_debug_config(config); 
    252249 
    253  
    254250    return config; 
    255251 
    256252} 
    257253 
    258 static xmlChar * 
    259 get_node_name(xmlNode * node) 
    260 { 
    261     return swish_xstrdup(node->name); 
    262 } 
    263  
    264 static xmlDocPtr  
    265 parse_xml_config(xmlChar * conf) 
    266 { 
    267     xmlDocPtr       doc; 
    268     struct stat     fileinfo; 
    269  
    270     /* parse either a filename, or, if we can't stat it, assume conf is a XML string */ 
    271     if (!stat((char *) conf, &fileinfo)) 
    272     { 
    273         doc = xmlParseFile((const char *) conf); 
    274         if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    275             SWISH_DEBUG_MSG("Parsing configuration file: %s", conf); 
    276     } 
    277     else 
    278     { 
    279         doc = xmlParseMemory((const char *) conf, xmlStrlen(conf)); 
    280         if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    281             SWISH_DEBUG_MSG("Parsing configuration from memory"); 
    282     } 
    283  
    284     if (doc == NULL) 
    285         SWISH_CROAK("error: could not parse XML: %s", conf); 
    286  
    287     return doc; 
    288  
    289 } 
    290  
    291  
    292 static xmlNode * 
    293 get_dom_root(xmlDocPtr doc) 
    294 { 
    295     xmlNode        *root = NULL; 
    296     xmlChar        *toptag = (xmlChar*)"swishconfig"; 
    297  
    298     root = xmlDocGetRootElement(doc); 
    299  
    300     /* -------------------------------------------------------------------------- 
    301      * Must have root element, a name and the name must be "swishconfig" 
    302      * -------------------------------------------------------------------------- */ 
    303     if (!root || 
    304         !root->name || 
    305         !xmlStrEqual(root->name, toptag)) 
    306     { 
    307         xmlFreeDoc(doc); 
    308         SWISH_CROAK("bad config format: malformed or missing '%s' toplevel tag", toptag); 
    309         return 0; 
    310     } 
    311  
    312     return root; 
    313 } 
    314  
    315  
    316254swish_Config  * 
    317 swish_parse_config(xmlChar * conf, swish_Config * config) 
    318 
    319     xmlNode        *cur_node, *root; 
    320     xmlChar        *opt_name, *opt_type, *opt_arg, *tmp_arg, *tmp_value; 
    321     int             name_seen, i, free_tmp; 
    322     swish_StringList *arg_list; 
    323     xmlHashTablePtr vhash; 
    324     xmlDocPtr       doc; 
    325  
    326     doc = parse_xml_config(conf); 
    327     root = get_dom_root(doc); 
    328  
    329     /* init all strings */ 
    330  
    331     opt_name = NULL; 
    332     opt_type = NULL; 
    333     opt_arg = NULL; 
    334  
    335  
    336     /* -------------------------------------------------------------------------- get 
    337      * options/values format is: 
    338      *  
    339      * <directive type="someval">some arg</directive> 
    340      *  
    341      * where type="someval" attr is optional -- defaults to whatever 'some arg' is 
    342      * -------------------------------------------------------------------------- */ 
    343  
    344     for (cur_node = root->children; cur_node != NULL; cur_node = cur_node->next) 
    345     { 
    346         if (cur_node->type == XML_ELEMENT_NODE) 
    347         { 
    348             /* fprintf(stderr, "Element: %s \n", cur_node->name); */ 
    349  
    350             opt_name = get_node_name(cur_node); 
    351  
    352             opt_type = xmlGetProp(cur_node, (xmlChar *) "type"); 
    353  
    354             opt_arg = xmlNodeGetContent(cur_node); 
    355  
    356             if (!opt_arg) 
    357                 SWISH_CROAK("no value for option tag '%s'", opt_name); 
    358  
    359             /* append value/args to any existing names in config */ 
    360             if (xmlHashLookup(config->misc, opt_name)) 
    361             { 
    362                 /* err(202,"Bad 'name' tag contents in config: already 
    363                  * seen '%s'\n", opt_name); */ 
    364                 vhash = xmlHashLookup(config->misc, opt_name); 
    365                 if (vhash == NULL) 
    366                 { 
    367                     SWISH_CROAK("error with existing name in config: %s", opt_name); 
    368                 } 
    369                 else 
    370                 { 
    371                     if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    372                         SWISH_DEBUG_MSG(" >>> found existing name in config: %s", opt_name); 
    373  
    374                     name_seen = 1; 
    375                 } 
    376  
    377             } 
    378             else 
    379             { 
    380                 name_seen = 0; 
    381  
    382                 vhash = swish_new_hash(16);    /* values => args */ 
    383                 if (vhash == NULL) 
    384                     SWISH_CROAK("error creating vhash"); 
    385  
    386             } 
    387  
    388  
    389             /* if we reference another config file, load it immediately but 
    390              * don't load into hash, as we might have multiple config files 
    391              * nested */ 
    392             if (xmlStrEqual(opt_name, (xmlChar *) SWISH_INCLUDE_FILE)) 
    393             { 
    394  
    395                 /* TODO deduce relative paths */ 
    396                 swish_parse_config(opt_arg, config); 
    397                 swish_xfree(opt_name); 
    398                 xmlFree(opt_arg); 
    399                 continue; 
    400  
    401             } 
    402  
    403             /* split arg and value into words/phrases and add each one to 
    404              * hash. This allows for multiple values in a single opt_name */ 
    405  
    406  
    407             arg_list = swish_make_stringlist(opt_arg); 
    408  
    409             for (i = 0; i < arg_list->n; i++) 
    410             { 
    411  
    412                 free_tmp = 0; 
    413                 tmp_arg = arg_list->word[i]; 
    414  
    415                 if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    416                     SWISH_DEBUG_MSG("config %s tmp_arg = %s  opt_type = %s", opt_name, tmp_arg, opt_type); 
    417  
    418                 tmp_value = opt_type ? swish_xstrdup(opt_type) : swish_xstrdup(tmp_arg); 
    419  
    420                 /* normalize all metanames and properties since we 
    421                  * compare against lc tag names */ 
    422                 if (xmlStrEqual(opt_name, (xmlChar *) SWISH_META) 
    423                     || 
    424                     xmlStrEqual(opt_name, (xmlChar *) SWISH_PROP) 
    425  
    426                     ) 
    427                 { 
    428                     free_tmp = 1; 
    429                     if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    430                         SWISH_DEBUG_MSG("tolower str: >%s<", tmp_arg); 
    431  
    432                     tmp_arg = swish_str_tolower(tmp_arg); // TODO mem leak !! ?? 
    433  
    434                 } 
    435  
    436                 if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    437                     SWISH_DEBUG_MSG("config %s tmp_arg = %s  tmp_value = %s", opt_name, tmp_arg, tmp_value); 
    438  
    439                 if (xmlHashLookup(vhash, tmp_arg)) 
    440                     swish_hash_replace(vhash, tmp_arg, tmp_value); 
    441                 else 
    442                     swish_hash_add(vhash, tmp_arg, tmp_value); 
    443  
    444                 if (free_tmp) 
    445                     swish_xfree(tmp_arg); 
    446  
    447  
    448             } 
    449  
    450             swish_free_stringlist(arg_list); 
    451  
    452             /* don't use our swish_xfree since it throws off memcount */ 
    453             xmlFree(opt_arg); 
    454  
    455             if (opt_type != NULL) 
    456                 xmlFree(opt_type); 
    457  
    458  
    459             /* add vhash to config hash unless we already have or it's just 
    460              * calling another config file */ 
    461             if (!name_seen && xmlStrcmp(opt_name, (xmlChar *) "IncludeConfigFile")) 
    462             { 
    463                 if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 
    464                     SWISH_DEBUG_MSG(" >>> adding %s to config hash ( name_seen = %d )", opt_name, name_seen); 
    465  
    466                 swish_hash_add(config->misc, opt_name, vhash); 
    467             } 
    468  
    469  
    470             swish_xfree(opt_name); 
    471  
    472         }        /* end XML_ELEMENT_NODE */ 
    473  
    474     }            /* end cur_node */ 
    475  
    476     xmlFreeDoc(doc); 
    477     xmlCleanupParser(); 
    478  
     255swish_parse_config(xmlChar *conf, swish_Config *config) 
     256
     257    swish_merge_config_with_header((char*)conf, config); 
    479258    return config; 
    480259} 
     
    519298 
    520299static void 
    521 copy_property( xmlHashTablePtr props1, swish_Property *prop2, xmlChar *prop2name ) 
     300copy_property( 
     301    swish_Property *prop2, 
     302    xmlHashTablePtr props1, 
     303    xmlChar *prop2name 
     304
    522305{ 
    523306    swish_Property *prop1; 
    524307    boolean in_hash; 
     308         
    525309    if (swish_hash_exists(props1, prop2name)) { 
    526310        prop1 = swish_hash_fetch(props1, prop2name); 
     
    529313    else { 
    530314        prop1 = swish_init_property(swish_xstrdup(prop2name)); 
     315        prop1->ref_cnt++; 
    531316        in_hash = 0; 
    532317    } 
    533318     
    534319    prop1->id            = prop2->id; 
    535     if (prop1->name != NULL) { 
     320    if (in_hash && prop1->name != NULL) { 
    536321        swish_xfree( prop1->name ); 
    537     } 
    538     prop1->name          = swish_xstrdup( prop2->name ); 
     322        prop1->name = swish_xstrdup( prop2->name ); 
     323    } 
    539324    prop1->ignore_case   = prop2->ignore_case; 
    540325    prop1->type          = prop2->type; 
     
    543328        swish_xfree( prop2->alias_for ); 
    544329    } 
    545     prop1->alias_for     = swish_xstrdup( prop2->alias_for ); 
     330    if (prop2->alias_for != NULL) { 
     331        prop1->alias_for     = swish_xstrdup( prop2->alias_for ); 
     332    } 
    546333    prop1->max           = prop2->max; 
    547334    prop1->sort          = prop2->sort; 
     
    550337        swish_hash_add(props1, prop1->name, prop1); 
    551338    } 
     339     
    552340} 
    553341 
     
    559347 
    560348static void 
    561 copy_metaname( xmlHashTablePtr metas1, swish_MetaName *meta2, xmlChar *meta2name ) 
     349copy_metaname( 
     350    swish_MetaName *meta2, 
     351    xmlHashTablePtr metas1, 
     352    xmlChar *meta2name  
     353
    562354{ 
    563355    swish_MetaName *meta1; 
     
    569361    else { 
    570362        meta1 = swish_init_metaname(swish_xstrdup(meta2name)); 
     363        meta1->ref_cnt++; 
    571364        in_hash = 0; 
    572365    } 
    573366 
    574367    meta1->id           = meta2->id; 
    575     if (meta1->name != NULL) { 
     368    if (in_hash && meta1->name != NULL) { 
    576369        swish_xfree(meta1->name); 
    577     } 
    578     meta1->name         = swish_xstrdup( meta2->name ); 
     370        meta1->name = swish_xstrdup( meta2->name ); 
     371    } 
    579372    meta1->bias         = meta2->bias; 
    580373    if (meta1->alias_for != NULL) { 
    581374        swish_xfree(meta1->alias_for); 
    582375    } 
    583     meta1->alias_for    = swish_xstrdup( meta2->alias_for ); 
     376    if (meta2->alias_for != NULL) { 
     377        meta1->alias_for    = swish_xstrdup( meta2->alias_for ); 
     378    } 
    584379     
    585380    if (!in_hash) { 
     
    597392swish_config_merge(swish_Config *config1, swish_Config *config2) 
    598393{ 
     394 
    599395    /* values in config2 override and are set in config1 */ 
     396    //SWISH_DEBUG_MSG("merge properties"); 
    600397    merge_properties(config1->properties,   config2->properties); 
     398    //SWISH_DEBUG_MSG("merge metanames"); 
    601399    merge_metanames(config1->metanames,     config2->metanames); 
     400    //SWISH_DEBUG_MSG("merge parsers"); 
    602401    swish_hash_merge(config1->parsers,      config2->parsers); 
     402    //SWISH_DEBUG_MSG("merge mimes"); 
    603403    swish_hash_merge(config1->mimes,        config2->mimes); 
     404    //SWISH_DEBUG_MSG("merge index"); 
    604405    swish_hash_merge(config1->index,        config2->index); 
     406    //SWISH_DEBUG_MSG("merge tag_aliases"); 
    605407    swish_hash_merge(config1->tag_aliases,  config2->tag_aliases); 
     408    //SWISH_DEBUG_MSG("merge misc"); 
    606409    swish_hash_merge(config1->misc,         config2->misc); 
    607410 
  • libswish3/trunk/src/libswish3/hash.c

    r2042 r2046  
    8282 
    8383xmlHashTablePtr  
    84 swish_new_hash(int size) 
     84swish_init_hash(int size) 
    8585{ 
    8686    xmlHashTablePtr h; 
  • libswish3/trunk/src/libswish3/header.c

    r2042 r2046  
    332332    value   = xmlTextReaderConstValue(reader); 
    333333     
     334    //SWISH_DEBUG_MSG("name %s  type %d  value %s", name, type, value); 
     335     
    334336    if (name == NULL) 
    335337            name = BAD_CAST "--"; 
     
    437439        }     
    438440        else if (type == XML_READER_TYPE_ELEMENT) { 
     441         
     442            //SWISH_DEBUG_MSG("misc header value"); 
    439443             
    440444            /* element. get text and add to misc */ 
     
    443447                    value = xmlTextReaderConstValue(reader); 
    444448                    if (swish_hash_exists(h->config->misc, (xmlChar*)name)) { 
    445                         swish_hash_replace(h->config->misc, swish_xstrdup(name), swish_xstrdup(value)); 
     449                        swish_hash_replace(h->config->misc, (xmlChar*)name, swish_xstrdup(value)); 
    446450                    } 
    447451                    else { 
    448                         swish_hash_add(h->config->misc, swish_xstrdup(name), swish_xstrdup(value)); 
     452                        swish_hash_add(h->config->misc, (xmlChar*)name, swish_xstrdup(value)); 
    449453                    } 
    450454                } 
     
    470474    xmlTextReaderPtr reader; 
    471475    int ret; 
    472  
    473     reader = xmlReaderForFile(filename, NULL, 0); 
     476    struct stat fileinfo; 
     477     
     478    /* parse either a filename, or, if we can't stat it,  
     479       assume conf is a XML string  
     480    */ 
     481    if (stat((char *)filename, &fileinfo)) { 
     482        reader = xmlReaderForMemory( 
     483                    (const char*)filename,  
     484                    xmlStrlen((xmlChar*)filename),  
     485                    "[ swish.xml ]",  
     486                    NULL, 
     487                    0); 
     488                     
     489        //SWISH_DEBUG_MSG("header parsed in-memory"); 
     490    } 
     491    else { 
     492        reader = xmlReaderForFile(filename, NULL, 0); 
     493         
     494        //SWISH_DEBUG_MSG("header parsed from file"); 
     495    } 
     496     
    474497    if (reader != NULL) { 
    475498        ret = xmlTextReaderRead(reader); 
     
    485508        SWISH_CROAK("Unable to open %s\n", filename); 
    486509    } 
     510     
     511    /* 
     512     * Cleanup function for the XML library. 
     513     */ 
     514    xmlCleanupParser(); 
    487515} 
    488516 
     
    503531{ 
    504532    headmaker *h; 
    505      
    506533    h = init_headmaker(); 
    507534    read_header( filename, h ); 
     
    509536    swish_free_config( h->config ); 
    510537    swish_xfree( h ); 
    511  
    512538    return 1; // how to test ? 
    513539} 
     
    517543{ 
    518544    headmaker *h; 
    519      
    520545    h = init_headmaker(); 
    521546    read_header( filename, h ); 
    522547    swish_config_merge( c, h->config ); 
     548    swish_free_config( h->config ); 
    523549    swish_xfree( h ); 
    524      
    525550    return 1; 
    526551} 
     552 
     553swish_Config * 
     554swish_read_header(char *filename) 
     555{ 
     556    headmaker *h; 
     557    swish_Config *c; 
     558    h = init_headmaker(); 
     559    read_header( filename, h ); 
     560    c = h->config; 
     561    swish_xfree( h ); 
     562    return c; 
     563} 
  • libswish3/trunk/src/libswish3/libswish3.h

    r2042 r2046  
    345345 
    346346/* 
     347=head2 Global Functions 
     348*/ 
     349void        swish_init(); 
     350/* 
     351=cut 
     352*/ 
     353 
     354/* 
    347355=head2 Object Functions 
    348356*/ 
     
    373381void        swish_hash_merge( xmlHashTablePtr hash1, xmlHashTablePtr hash2 ); 
    374382void *      swish_hash_fetch( xmlHashTablePtr hash, xmlChar *key ); 
    375 xmlHashTablePtr swish_new_hash(int size); 
     383xmlHashTablePtr swish_init_hash(int size); 
    376384/* 
    377385=cut 
     
    599607boolean         swish_validate_header(char *filename); 
    600608boolean         swish_merge_config_with_header(char *filename, swish_Config *c); 
     609swish_Config *  swish_read_header(char *filename); 
    601610/* 
    602611=cut 
  • libswish3/trunk/src/libswish3/swish.c

    r2042 r2046  
    2323int SWISH_DEBUG = 0; /* global var */ 
    2424 
    25 void static swish_init(); 
    2625 
    2726swish_3* 
     
    7372 
    7473 
    75 void static 
     74void 
    7675swish_init() 
    7776{ 
     
    102101    } 
    103102         
    104          
     103    /* 
     104     * initialize the library and check potential API mismatches 
     105     * between the version it was compiled for and the actual shared 
     106     * library used. 
     107     */ 
     108    LIBXML_TEST_VERSION 
    105109 
    106110    swish_init_memory(); 
  • libswish3/trunk/src/swish_header.c

    r2042 r2046  
    3636#ifdef LIBXML_READER_ENABLED 
    3737    int i; 
    38  
    39     /* 
    40      * initialize the library and check potential API mismatches 
    41      * between the version it was compiled for and the actual shared 
    42      * library used. 
    43      */ 
    44     LIBXML_TEST_VERSION 
     38    swish_Config *config; 
     39     
     40    swish_init();     
    4541 
    4642    for (i=1; i < argc; i++) { 
    47  
    4843        printf("config file %s\n", argv[i]); 
    49         if (swish_validate_header( (char*)argv[i] )) { 
    50             printf("%s ok\n", argv[i]); 
    51         } 
    52         else { 
    53             fprintf(stderr, "%s failed\n", argv[i]); 
    54         } 
    55  
     44        config = swish_read_header( (char*)argv[i] ); 
     45        swish_debug_config(config); 
     46        swish_free_config(config); 
    5647    } 
    5748         
    58     /* 
    59      * Cleanup function for the XML library. 
    60      */ 
    61     xmlCleanupParser(); 
     49     
    6250    /* 
    6351     * this is to debug memory for regression tests