Changeset 2046
- Timestamp:
- 03/07/08 22:33:11 (2 months ago)
- Files:
-
- libswish3/trunk/src/example (added)
- libswish3/trunk/src/example/swish.xml (added)
- libswish3/trunk/src/libswish3/config.c (modified) (12 diffs)
- libswish3/trunk/src/libswish3/hash.c (modified) (1 diff)
- libswish3/trunk/src/libswish3/header.c (modified) (8 diffs)
- libswish3/trunk/src/libswish3/libswish3.h (modified) (3 diffs)
- libswish3/trunk/src/libswish3/swish.c (modified) (3 diffs)
- libswish3/trunk/src/swish_header.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
libswish3/trunk/src/libswish3/config.c
r2042 r2046 39 39 40 40 static 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 46 41 static void free_string(xmlChar *payload, xmlChar *key); 47 42 static void free_props(swish_Property *prop, xmlChar *propname); … … 65 60 } 66 61 prop->ref_cnt--; 67 swish_free_property(prop); 62 if (prop->ref_cnt < 1) { 63 swish_free_property(prop); 64 } 68 65 } 69 66 … … 76 73 } 77 74 meta->ref_cnt--; 78 swish_free_metaname(meta); 75 if (meta->ref_cnt < 1) { 76 swish_free_metaname(meta); 77 } 79 78 } 80 79 … … 120 119 config = swish_xmalloc(sizeof(swish_Config)); 121 120 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); 128 127 config->mimes = NULL; 129 128 config->ref_cnt = 0; … … 241 240 } 242 241 243 /* PUBLIC */ 244 swish_Config * 245 swish_add_config(xmlChar * conf, swish_Config * config) 242 swish_Config * 243 swish_add_config(xmlChar *conf, swish_Config *config) 246 244 { 247 245 248 246 config = swish_parse_config(conf, config); 249 250 247 if (SWISH_DEBUG >= SWISH_DEBUG_CONFIG) 251 248 swish_debug_config(config); 252 249 253 254 250 return config; 255 251 256 252 } 257 253 258 static xmlChar *259 get_node_name(xmlNode * node)260 {261 return swish_xstrdup(node->name);262 }263 264 static xmlDocPtr265 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 else278 {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 316 254 swish_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 255 swish_parse_config(xmlChar *conf, swish_Config *config) 256 { 257 swish_merge_config_with_header((char*)conf, config); 479 258 return config; 480 259 } … … 519 298 520 299 static void 521 copy_property( xmlHashTablePtr props1, swish_Property *prop2, xmlChar *prop2name ) 300 copy_property( 301 swish_Property *prop2, 302 xmlHashTablePtr props1, 303 xmlChar *prop2name 304 ) 522 305 { 523 306 swish_Property *prop1; 524 307 boolean in_hash; 308 525 309 if (swish_hash_exists(props1, prop2name)) { 526 310 prop1 = swish_hash_fetch(props1, prop2name); … … 529 313 else { 530 314 prop1 = swish_init_property(swish_xstrdup(prop2name)); 315 prop1->ref_cnt++; 531 316 in_hash = 0; 532 317 } 533 318 534 319 prop1->id = prop2->id; 535 if ( prop1->name != NULL) {320 if (in_hash && prop1->name != NULL) { 536 321 swish_xfree( prop1->name ); 537 }538 prop1->name = swish_xstrdup( prop2->name );322 prop1->name = swish_xstrdup( prop2->name ); 323 } 539 324 prop1->ignore_case = prop2->ignore_case; 540 325 prop1->type = prop2->type; … … 543 328 swish_xfree( prop2->alias_for ); 544 329 } 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 } 546 333 prop1->max = prop2->max; 547 334 prop1->sort = prop2->sort; … … 550 337 swish_hash_add(props1, prop1->name, prop1); 551 338 } 339 552 340 } 553 341 … … 559 347 560 348 static void 561 copy_metaname( xmlHashTablePtr metas1, swish_MetaName *meta2, xmlChar *meta2name ) 349 copy_metaname( 350 swish_MetaName *meta2, 351 xmlHashTablePtr metas1, 352 xmlChar *meta2name 353 ) 562 354 { 563 355 swish_MetaName *meta1; … … 569 361 else { 570 362 meta1 = swish_init_metaname(swish_xstrdup(meta2name)); 363 meta1->ref_cnt++; 571 364 in_hash = 0; 572 365 } 573 366 574 367 meta1->id = meta2->id; 575 if ( meta1->name != NULL) {368 if (in_hash && meta1->name != NULL) { 576 369 swish_xfree(meta1->name); 577 }578 meta1->name = swish_xstrdup( meta2->name );370 meta1->name = swish_xstrdup( meta2->name ); 371 } 579 372 meta1->bias = meta2->bias; 580 373 if (meta1->alias_for != NULL) { 581 374 swish_xfree(meta1->alias_for); 582 375 } 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 } 584 379 585 380 if (!in_hash) { … … 597 392 swish_config_merge(swish_Config *config1, swish_Config *config2) 598 393 { 394 599 395 /* values in config2 override and are set in config1 */ 396 //SWISH_DEBUG_MSG("merge properties"); 600 397 merge_properties(config1->properties, config2->properties); 398 //SWISH_DEBUG_MSG("merge metanames"); 601 399 merge_metanames(config1->metanames, config2->metanames); 400 //SWISH_DEBUG_MSG("merge parsers"); 602 401 swish_hash_merge(config1->parsers, config2->parsers); 402 //SWISH_DEBUG_MSG("merge mimes"); 603 403 swish_hash_merge(config1->mimes, config2->mimes); 404 //SWISH_DEBUG_MSG("merge index"); 604 405 swish_hash_merge(config1->index, config2->index); 406 //SWISH_DEBUG_MSG("merge tag_aliases"); 605 407 swish_hash_merge(config1->tag_aliases, config2->tag_aliases); 408 //SWISH_DEBUG_MSG("merge misc"); 606 409 swish_hash_merge(config1->misc, config2->misc); 607 410 libswish3/trunk/src/libswish3/hash.c
r2042 r2046 82 82 83 83 xmlHashTablePtr 84 swish_ new_hash(int size)84 swish_init_hash(int size) 85 85 { 86 86 xmlHashTablePtr h; libswish3/trunk/src/libswish3/header.c
r2042 r2046 332 332 value = xmlTextReaderConstValue(reader); 333 333 334 //SWISH_DEBUG_MSG("name %s type %d value %s", name, type, value); 335 334 336 if (name == NULL) 335 337 name = BAD_CAST "--"; … … 437 439 } 438 440 else if (type == XML_READER_TYPE_ELEMENT) { 441 442 //SWISH_DEBUG_MSG("misc header value"); 439 443 440 444 /* element. get text and add to misc */ … … 443 447 value = xmlTextReaderConstValue(reader); 444 448 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)); 446 450 } 447 451 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)); 449 453 } 450 454 } … … 470 474 xmlTextReaderPtr reader; 471 475 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 474 497 if (reader != NULL) { 475 498 ret = xmlTextReaderRead(reader); … … 485 508 SWISH_CROAK("Unable to open %s\n", filename); 486 509 } 510 511 /* 512 * Cleanup function for the XML library. 513 */ 514 xmlCleanupParser(); 487 515 } 488 516 … … 503 531 { 504 532 headmaker *h; 505 506 533 h = init_headmaker(); 507 534 read_header( filename, h ); … … 509 536 swish_free_config( h->config ); 510 537 swish_xfree( h ); 511 512 538 return 1; // how to test ? 513 539 } … … 517 543 { 518 544 headmaker *h; 519 520 545 h = init_headmaker(); 521 546 read_header( filename, h ); 522 547 swish_config_merge( c, h->config ); 548 swish_free_config( h->config ); 523 549 swish_xfree( h ); 524 525 550 return 1; 526 551 } 552 553 swish_Config * 554 swish_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 345 345 346 346 /* 347 =head2 Global Functions 348 */ 349 void swish_init(); 350 /* 351 =cut 352 */ 353 354 /* 347 355 =head2 Object Functions 348 356 */ … … 373 381 void swish_hash_merge( xmlHashTablePtr hash1, xmlHashTablePtr hash2 ); 374 382 void * swish_hash_fetch( xmlHashTablePtr hash, xmlChar *key ); 375 xmlHashTablePtr swish_ new_hash(int size);383 xmlHashTablePtr swish_init_hash(int size); 376 384 /* 377 385 =cut … … 599 607 boolean swish_validate_header(char *filename); 600 608 boolean swish_merge_config_with_header(char *filename, swish_Config *c); 609 swish_Config * swish_read_header(char *filename); 601 610 /* 602 611 =cut libswish3/trunk/src/libswish3/swish.c
r2042 r2046 23 23 int SWISH_DEBUG = 0; /* global var */ 24 24 25 void static swish_init();26 25 27 26 swish_3* … … 73 72 74 73 75 void static74 void 76 75 swish_init() 77 76 { … … 102 101 } 103 102 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 105 109 106 110 swish_init_memory(); libswish3/trunk/src/swish_header.c
r2042 r2046 36 36 #ifdef LIBXML_READER_ENABLED 37 37 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(); 45 41 46 42 for (i=1; i < argc; i++) { 47 48 43 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); 56 47 } 57 48 58 /* 59 * Cleanup function for the XML library. 60 */ 61 xmlCleanupParser(); 49 62 50 /* 63 51 * this is to debug memory for regression tests
