/*************************************************************************
* Log file format reading code
* Copyright (c) 1998-9 Andy Kempling (aurikan@hotmail.com),
* Copyright (c) 1998-2001 Colin Phipps (cph@lxdoom.linuxgames.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*************************************************************************/
/* $Id: log_regexp.c,v 1.7 2001/07/21 10:18:18 cph Exp $ */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include "ircstats.h"
const char nick_exp[] = { "^ @<>!:*" };
const char uh_exp[] = { "^ :!*" };
const char nick_sub[] = { "[:nick:]" };
const char uh_sub[] = { "[:uh:]" };
static const char* make_regexp(const char* str)
{
size_t l;
/* FUDGE: roughly speaking, even in the worse case we aren't likely
* to expand by much more than a factor of 3 */
char *p = calloc(l = 3*strlen(str), sizeof(char));
char *q = p;
while (*str) {
if (!strncmp(str, nick_sub, sizeof(nick_sub)-1)) {
str += sizeof(nick_sub)-1;
strcat(p, nick_exp); q += sizeof(nick_exp)-1;
} else if (!strncmp(str, uh_sub, sizeof(uh_sub)-1)) {
str += sizeof(uh_sub)-1;
strcat(p, uh_exp); q += sizeof(uh_exp)-1;
} else *q++ = *str++;
}
return p;
}
/* One string for each LT_type */
const char* lt_strings[] = { "null","text","act","join","part","quit","kick","topic","nick","mode","date_stamp","channel"};
/* One string for each LP_thing */
const char* lp_strings[] = { "time","nick","othernick","string","date","channel"};
struct log_parse_s* ReadLogFormatSpec(FILE* infp, int verbose)
{
#define BUFLEN 2048
struct log_parse_s* plp = calloc(sizeof(struct log_parse_s), LT_NUM);
char buf[BUFLEN];
char lt_done[LT_NUM];
int i;
memset(lt_done,0,sizeof(lt_done)); lt_done[0] = 1; /* We want everything but null */
if (sizeof(lt_strings) / sizeof(lt_strings[0]) != LT_NUM) {
fprintf(stderr, "ReadLogFormatSpec: Internal LT inconsistency\n");
exit(-1);
}
if (sizeof(lp_strings) / sizeof(lp_strings[0]) != LP_NUM) {
fprintf(stderr, "ReadLogFormatSpec: Internal LP inconsistency\n");
exit(-1);
}
while (1) {
char *p,*q;
if (!fgets(buf, BUFLEN, infp)) {
if (feof(infp)) {
for (i=0; i<LT_NUM; i++)
if (!lt_done[i]) {
fprintf(stderr, "No definition of %s found in format spec\n", lt_strings[i]);
exit(-1);
}
return plp;
} else {
perror("ReadLogFormatSpec");
exit(-1);
}
}
if ((p = strchr(buf,';'))) *p = 0; /* Remove comments */
if ((p = strchr(buf,'\n'))) *p = 0; /* Remove trailing newline */
if ((p = strchr(buf,'='))) {
enum line_type_e lt;
*p++ = 0;
for (i=0; i<LT_NUM; i++)
if (!strcasecmp(buf, lt_strings[i])) break;
lt = i;
if (i == LT_NUM) fprintf(stderr, "Unrecognised line type %s\n", buf);
else if (!*p) fprintf(stderr, "Bad regexp for %s\n", lt_strings[lt]);
else if (lt_done[lt]) fprintf(stderr, "Repeat definition ignored for %s\n", lt_strings[lt]);
else {
int rc;
q = strchr(p,',');
if (q) *q++ = 0;
p = make_regexp(p);
if (!(rc = regcomp(&plp[lt].compiled_regex, p, REG_EXTENDED))) {
if (verbose>1) fprintf(stderr, "Compiled regexp \"%s\" for %s\n", p, lt_strings[lt]);
free(p);
lt_done[lt] = 1; i = 0;
while ((p = q) && *q) {
int j;
i++;
q = strchr(p, ',');
if (q) *q++ = 0;
for (j=0; j<LP_NUM; j++)
if (!strcasecmp(p, lp_strings[j])) break;
if (strcasecmp(p, "null")) {
if (j == LP_NUM) fprintf(stderr, "Unknown line part %s\n", p);
else plp[lt].returned_bit[j] = i;
}
}
} else {
char errbuf[BUFLEN];
regerror(rc, &plp[lt].compiled_regex, errbuf, BUFLEN);
fprintf(stderr, "Error in \"%s\" - %s\n", p, errbuf);
free(p);
}
}
}
}
return NULL; /* Unreached */
}
syntax highlighted by Code2HTML, v. 0.9.1