add: case '{': p++;  if((*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z')) { LOG(L_ERR, "xlog: xl_parse_format: error parsing format" " [%s] pos [%d]\n", s, (int)(p-s)); goto error; } e->hparam.s = p; while(*p && *p!='}' && *p!='[') p++; if(*p == '\0') { LOG(L_ERR, "xlog: xl_parse_format: error parsing format" " [%s] expecting '}' after position [%d]\n", s, (int)(e->hparam.s-s)); goto error; }  e->hparam.len = p - e->hparam.s;  if(*p == '[') { p++; if(*p=='-') { p++; if(*p!='1') { LOG(L_ERR, "xlog: xl_parse_format: error" " parsing format [%s] -- only -1 is accepted" " as a negative index\n", s); goto error; } e->hindex = -1; p++; } else { while(*p>='0' && *p<='9') { e->hindex = e->hindex * 10 + *p - '0'; p++; } } if(*p != ']') { LOG(L_ERR, "xlog: xl_parse_format: error parsing format" " [%s] expecting ']' after position [%d]\n", s, (int)(e->hparam.s - s + e->hparam.len)); goto error; } p++; } if(*p != '}') { LOG(L_ERR, "xlog: xl_parse_format: error parsing format" " [%s] expecting '}' after position [%d]!\n", s, (int)(e->hparam.s-s)); goto error; } e->itf = xl_get_header;  DBG("xlog: xl_parse_format: header name [%.*s] index [%d]\n", e->hparam.len, e->hparam.s, e->hindex); break;
context: int xl_parse_format(char *s, xl_elog_p *el){	char *p;	int n = 0;	xl_elog_p e, e0;		if(s==NULL || el==NULL)		return -1;	DBG("XLOG: xl_parse_format: parsing [%s]\n", s);		p = s;	*el = NULL;	e = e0 = NULL;	while(*p)	{		e0 = e;		e = pkg_malloc(sizeof(xl_elog_t));		if(!e)			goto error;		memset(e, 0, sizeof(xl_elog_t));		n++;		if(*el == NULL)			*el = e;		if(e0)			e0->next = e;			e->text.s = p;		while(*p && *p!='%')			p++;		e->text.len = p - e->text.s;		if(*p == '\0')			break;		p++;		switch(*p)		{			case 'c':				p++;				switch(*p)				{					case 'i':						e->itf = xl_get_callid;					break;					case 's':						e->itf = xl_get_cseq;					break;					case 't':						e->itf = xl_get_contact;					break;					default:						e->itf = xl_get_null;				}			break;			case 'f':				p++;				switch(*p)				{					case 'u':						e->itf = xl_get_from;					break;					case 't':						e->itf = xl_get_from_tag;					break;					default:						e->itf = xl_get_null;				}			break;			case 'i':				p++;				switch(*p)				{					case 's':						e->itf = xl_get_srcip;					break;					default:					e->itf = xl_get_null; 							}			break;			case 'm':				p++;				switch(*p)				{					case 'b':						e->itf = xl_get_msg_buf;					break;					case 'f':						e->itf = xl_get_flags;					break;					case 'i':						e->itf = xl_get_msgid;					break;					case 'l':						e->itf = xl_get_msg_len;					break;					default:						e->itf = xl_get_null;				}				break;			case 'p':				p++;				switch(*p)				{					case 'p':						e->itf = xl_get_pid;					break;					default:						e->itf = xl_get_null;				}			break;			case 'r':				p++;				switch(*p)				{					case 'm':						e->itf = xl_get_method;					break;					case 'u':						e->itf = xl_get_ruri;					break;					case 's':						e->itf = xl_get_status;					break;					case 'r':						e->itf = xl_get_reason;					break;					default:						e->itf = xl_get_null;				}			break;			case 't':				p++;				switch(*p)				{					case 'u':						e->itf = xl_get_to;					break;					case 't':						e->itf = xl_get_to_tag;					break;					default:						e->itf = xl_get_null;				}			break;			case 'T':				p++;				switch(*p)				{					case 's':						e->itf = xl_get_times;					break;					case 'f':						e->itf = xl_get_timef;					break;					default:						e->itf = xl_get_null;				}			break;			case 'u':				p++;				switch(*p)				{					case 'a':						e->itf = xl_get_useragent;					break;					default:						e->itf = xl_get_null;				}			break;			case '%':				e->itf = xl_get_percent;			break;			default:				e->itf = xl_get_null;		}		if(*p == '\0')			break;		p++;	}	DBG("XLOG: xl_parse_format: format parsed OK: [%d] items\n", n);	return 0;error:	xl_elog_free_all(*el);	*el = NULL;	return -1;}