260 } |
249 } |
261 sstr_t ns; |
250 sstr_t ns; |
262 ns.ptr = NULL; |
251 ns.ptr = NULL; |
263 ns.length = 0; |
252 ns.length = 0; |
264 return ns; |
253 return ns; |
|
254 } |
|
255 |
|
256 /* |
|
257 * parses a line containing a directive and returns a ConfigDirective object |
|
258 * or NULL if an error occurs |
|
259 */ |
|
260 ConfigDirective* cfg_parse_directive(sstr_t line, UcxMempool *mp) { |
|
261 if(line.length < 6) { |
|
262 return NULL; // line too short |
|
263 } |
|
264 |
|
265 sstr_t name; |
|
266 |
|
267 int i; |
|
268 for(i=0;i<line.length;i++) { |
|
269 if(line.ptr[i] < 33) { |
|
270 break; |
|
271 } |
|
272 } |
|
273 name.ptr = line.ptr; |
|
274 name.length = i; |
|
275 |
|
276 // create directive object |
|
277 ConfigDirective *directive = OBJ_NEW(mp, ConfigDirective); |
|
278 directive->directive_type = sstrdub_mp(mp, name); |
|
279 directive->type_num = cfg_get_directive_type_num(name); |
|
280 directive->condition = NULL; // set later by main parsing function |
|
281 directive->param = NULL; |
|
282 |
|
283 sstr_t param_str; |
|
284 param_str.ptr = name.ptr + i; |
|
285 param_str.length = line.length - i; |
|
286 param_str = sstrtrim(param_str); |
|
287 sstr_t pname; |
|
288 sstr_t pvalue; |
|
289 for(;;) { |
|
290 param_str = cfg_param(param_str, &pname, &pvalue); |
|
291 if(pname.length <= 0) { |
|
292 break; |
|
293 } |
|
294 |
|
295 // create param object |
|
296 ConfigParam *param = OBJ_NEW(mp, ConfigParam); |
|
297 param->name = sstrdub_mp(mp, pname); |
|
298 if(pvalue.length > 0) { |
|
299 param->value = sstrdub_mp(mp, pvalue); |
|
300 } else { |
|
301 param->value.ptr = NULL; |
|
302 param->value.length = 0; |
|
303 } |
|
304 |
|
305 // add param to list |
|
306 directive->param = ucx_list_append(directive->param, param); |
|
307 } |
|
308 |
|
309 return directive; |
265 } |
310 } |
266 |
311 |
267 /* |
312 /* |
268 * gets the directive type number from a type string |
313 * gets the directive type number from a type string |
269 * valid types are: |
314 * valid types are: |
293 } else if(sstrcmp(type, sstr("Init")) == 0) { |
338 } else if(sstrcmp(type, sstr("Init")) == 0) { |
294 dt = 6; |
339 dt = 6; |
295 } |
340 } |
296 return dt; |
341 return dt; |
297 } |
342 } |
|
343 |
|
344 /* |
|
345 * checks if the line contains only a comment or space |
|
346 */ |
|
347 int cfg_get_basic_type(sstr_t line) { |
|
348 if(line.length == 0) { |
|
349 return LINE_NOCONTENT; |
|
350 } else if(line.ptr[0] == '#') { |
|
351 return LINE_NOCONTENT; |
|
352 } |
|
353 return LINE_OTHER; |
|
354 } |
|
355 |
|
356 /* |
|
357 * checks if the line contains a begin/end tag or a directive |
|
358 */ |
|
359 int cfg_get_line_type(sstr_t line) { |
|
360 if(line.length < 3) { |
|
361 // this line is to short to be correct |
|
362 return LINE_ERROR; |
|
363 } |
|
364 |
|
365 if(line.ptr[0] == '<') { |
|
366 // start or end tag |
|
367 // TODO: check for space between '<' and '/' |
|
368 if(line.ptr[1] == '/') { |
|
369 return LINE_END_TAG; |
|
370 } else { |
|
371 return LINE_BEGIN_TAG; |
|
372 } |
|
373 } else { |
|
374 return LINE_DIRECTIVE; |
|
375 } |
|
376 } |
|
377 |
|
378 int cfg_get_tag_type(sstr_t tag) { |
|
379 if(!sstrcmp(tag, sstr("Object"))) { |
|
380 return TAG_OBJECT; |
|
381 } else if(!sstrcmp(tag, sstr("If"))) { |
|
382 return TAG_IF; |
|
383 } else if(!sstrcmp(tag, sstr("ElseIf"))) { |
|
384 return TAG_ELSEIF; |
|
385 } else if(!sstrcmp(tag, sstr("Else"))) { |
|
386 return TAG_ELSE; |
|
387 } else if(!sstrcmp(tag, sstr("Client"))) { |
|
388 return TAG_CLIENT; |
|
389 } |
|
390 return -1; |
|
391 } |
|
392 |
|
393 /* |
|
394 * returns the name of the ending tag |
|
395 * on error, this functions returns a zero length string |
|
396 */ |
|
397 sstr_t cfg_get_end_tag_name(sstr_t line) { |
|
398 sstr_t ns; |
|
399 ns.ptr = NULL; |
|
400 ns.length = 0; |
|
401 |
|
402 if(line.length < 4) { |
|
403 // minimum of 4 chars: </a> |
|
404 return ns; |
|
405 } |
|
406 |
|
407 sstr_t name; |
|
408 name.ptr = line.ptr + 2; |
|
409 name.length = line.length - 3; |
|
410 |
|
411 // check for </ > frame |
|
412 if(line.ptr[0] != '<' |
|
413 || line.ptr[1] != '/' |
|
414 || line.ptr[line.length - 1] != '>') |
|
415 { |
|
416 return ns; |
|
417 } |
|
418 |
|
419 return sstrtrim(name); |
|
420 } |
|
421 |
|
422 ConfigTag* cfg_parse_begin_tag(sstr_t line, UcxMempool *mp) { |
|
423 if(line.length < 4) { |
|
424 return NULL; // this line can't contain a valid tag |
|
425 } |
|
426 |
|
427 if(line.ptr[0] != '<' || line.ptr[line.length - 1] != '>') { |
|
428 return NULL; // syntax error |
|
429 } |
|
430 |
|
431 sstr_t name; |
|
432 name.ptr = line.ptr + 1; |
|
433 int i; |
|
434 for(i=1;i<line.length - 1;i++) { |
|
435 if(line.ptr[i] < 33) { // char is space |
|
436 name.length = i - 1; |
|
437 break; |
|
438 } |
|
439 } |
|
440 if(name.length < 1) { |
|
441 return NULL; // syntax error |
|
442 } |
|
443 |
|
444 // create tag object |
|
445 ConfigTag *tag = OBJ_NEW(mp, ConfigTag); |
|
446 tag->name = sstrdub_mp(mp, name); |
|
447 tag->param = NULL; |
|
448 |
|
449 // parse parameters |
|
450 sstr_t param_str; |
|
451 param_str.ptr = line.ptr + i; |
|
452 param_str.length = line.length - name.length - 2; |
|
453 param_str = sstrtrim(param_str); |
|
454 if(param_str.length <= 0) { |
|
455 return tag; // no parameters |
|
456 } |
|
457 |
|
458 sstr_t pname; |
|
459 sstr_t pvalue; |
|
460 for(;;) { |
|
461 param_str = cfg_param(param_str, &pname, &pvalue); |
|
462 if(pname.length <= 0) { |
|
463 break; |
|
464 } |
|
465 |
|
466 // create param object |
|
467 ConfigParam *param = OBJ_NEW(mp, ConfigParam); |
|
468 param->name = sstrdub_mp(mp, pname); |
|
469 if(pvalue.length > 0) { |
|
470 param->value = sstrdub_mp(mp, pvalue); |
|
471 } else { |
|
472 param->value.ptr = NULL; |
|
473 param->value.length = 0; |
|
474 } |
|
475 |
|
476 // add param to list |
|
477 tag->param = ucx_list_append(tag->param, param); |
|
478 } |
|
479 |
|
480 return tag; |
|
481 } |