* MATE -- Meta Analysis Tracing Engine
* Utility Library: Single Copy Strings and Attribute Value Pairs
*
-* Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+* Copyright 2004, Luis E. Garcia Ontanon <luis@ontanon.org>
*
* $Id$
*
-* Ethereal - Network traffic analyzer
-* By Gerald Combs <gerald@ethereal.com>
+* Wireshark - Network traffic analyzer
+* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include "config.h"
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
#include "mate.h"
#include "mate_util.h"
+#include <wsutil/file_util.h>
-/* TODO:
-+ fix debug_print levels
-+ chunks for scs_strings (do I realy need em??)
- + checking bounds in (almost) every operator
-- operators
- + rethink '&' operator
- - bounds check on op_match()
- ? change &{} into []
- ? add {xxx} to get avps named xxxx from the src avpl
- ? add (yyy) to do aaa+31 or and similar stuff
- - add perlre operator?
- - transform
- + map (N->M hash)
-*/
+/***************************************************************************
+* ADDRDIFF
+***************************************************************************
+* This is a macro that computes the difference between the raw address
+* values of two pointers (rather than the difference between the pointers)
+* as a ptrdiff_t.
+***************************************************************************/
+#define ADDRDIFF(p,q) (((char *)(void *)(p)) - ((char *)(void *)(q)))
/***************************************************************************
* fmt, ...: what to print
*/
-void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) {
- static guint8 debug_buffer[DEBUG_BUFFER_SIZE];
+void dbg_print(const gint* which, gint how, FILE* where, const gchar* fmt, ... ) {
+ static gchar debug_buffer[DEBUG_BUFFER_SIZE];
va_list list;
if ( ! which || *which < how ) return;
va_end( list );
if (! where) {
- g_message(debug_buffer);
+ g_message("%s", debug_buffer);
} else {
fputs(debug_buffer,where);
+ fputs("\n",where);
}
}
/***************************************************************************
* single copy strings
***************************************************************************
- * In order to save memory and since strings repeat more often than don't,
+ * Strings repeat more often than don't. In order to save memory
* we'll keep only one copy of each as key to a hash with a count of
* subscribers as value.
***************************************************************************/
-/* FIXME: use hash fom glib 1.X not 2.X */
/**
* scs_init:
struct _scs_collection {
GHashTable* hash; /* key: a string value: guint number of subscribers */
GMemChunk* ctrs;
- GMemChunk* mate_small;
+ GMemChunk* mate_small;
GMemChunk* mate_medium;
GMemChunk* mate_large;
GMemChunk* mate_huge;
if ( c->mate_medium ) g_mem_chunk_destroy(c->mate_medium);
if ( c->mate_large ) g_mem_chunk_destroy(c->mate_large);
if ( c->mate_huge ) g_mem_chunk_destroy(c->mate_huge);
-
+
if (c->hash) g_hash_table_destroy(c->hash);
}
SCS_collection* c = g_malloc(sizeof(SCS_collection));
c->hash = g_hash_table_new(g_str_hash,g_str_equal);
-
+
c->ctrs = g_mem_chunk_new("ints_scs_chunk", sizeof(guint),
sizeof(guint) * SCS_SMALL_CHUNK_SIZE, G_ALLOC_AND_FREE);
-
+
c->mate_small = g_mem_chunk_new("small_scs_chunk", SCS_SMALL_SIZE,
SCS_SMALL_SIZE * SCS_SMALL_CHUNK_SIZE, G_ALLOC_AND_FREE);
-
+
c->mate_medium = g_mem_chunk_new("medium_scs_chunk", SCS_MEDIUM_SIZE,
SCS_MEDIUM_SIZE * SCS_MEDIUM_CHUNK_SIZE, G_ALLOC_AND_FREE);
-
+
c->mate_large = g_mem_chunk_new("large_scs_chunk", SCS_LARGE_SIZE,
SCS_LARGE_SIZE * SCS_LARGE_CHUNK_SIZE, G_ALLOC_AND_FREE);
-
+
c->mate_huge = g_mem_chunk_new("huge_scs_chunk", SCS_HUGE_SIZE,
SCS_HUGE_SIZE * SCS_HUGE_CHUNK_SIZE, G_ALLOC_AND_FREE);
return c;
*
* Return value: a pointer to the subscribed string.
**/
-guint8* scs_subscribe(SCS_collection* c, guint8* s) {
- guint8* orig = NULL;
+gchar* scs_subscribe(SCS_collection* c, const gchar* s) {
+ gchar* orig = NULL;
guint* ip = NULL;
size_t len = 0;
GMemChunk* chunk = NULL;
-
- g_hash_table_lookup_extended(c->hash,s,(gpointer*)&orig,(gpointer*)&ip);
+
+ g_hash_table_lookup_extended(c->hash,(gconstpointer)s,(gpointer)&orig,(gpointer)&ip);
if (ip) {
(*ip)++;
} else {
ip = g_mem_chunk_alloc(c->ctrs);
*ip = 0;
-
+
len = strlen(s) + 1;
-
+
if (len <= SCS_SMALL_SIZE) {
chunk = c->mate_small;
len = SCS_SMALL_SIZE;
len = SCS_HUGE_SIZE;
g_warning("mate SCS: string truncated to huge size");
}
-
+
orig = g_mem_chunk_alloc(chunk);
strncpy(orig,s,len);
-
+
g_hash_table_insert(c->hash,orig,ip);
}
* decreases the count of subscribers, if zero frees the internal copy of
* the string.
**/
-void scs_unsubscribe(SCS_collection* c, guint8* s) {
- guint8* orig = NULL;
+void scs_unsubscribe(SCS_collection* c, gchar* s) {
+ gchar* orig = NULL;
guint* ip = NULL;
size_t len = 0xffff;
GMemChunk* chunk = NULL;
-
- g_hash_table_lookup_extended(c->hash,s,(gpointer*)&orig,(gpointer*)&ip);
+
+ g_hash_table_lookup_extended(c->hash,(gconstpointer)s,(gpointer)&orig,(gpointer)&ip);
if (ip) {
if (*ip == 0) {
g_hash_table_remove(c->hash,orig);
-
+
len = strlen(orig);
-
+
if (len < SCS_SMALL_SIZE) {
chunk = c->mate_small;
} else if (len < SCS_MEDIUM_SIZE) {
chunk = c->mate_large;
} else {
chunk = c->mate_huge;
- }
-
+ }
+
g_mem_chunk_free(chunk,orig);
g_mem_chunk_free(c->ctrs,ip);
}
(*ip)--;
}
} else {
- g_warning("unsusbcribe: already deleted: '%s'?",s);
+ g_warning("unsusbcribe: not subscribed");
}
}
* Return value: the stored copy of the formated string.
*
**/
-extern guint8* scs_subscribe_printf(SCS_collection* c, guint8* fmt, ...) {
+gchar* scs_subscribe_printf(SCS_collection* c, gchar* fmt, ...) {
va_list list;
- static guint8 buf[SCS_HUGE_SIZE];
-
+ static gchar buf[SCS_HUGE_SIZE];
+
va_start( list, fmt );
g_vsnprintf(buf, SCS_HUGE_SIZE-1 ,fmt, list);
va_end( list );
return scs_subscribe(c,buf);
}
-extern guint8* scs_subscribe_int(SCS_collection* c, int i) {
- static guint8 buf[SCS_SMALL_SIZE];
-
- g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%i", i);
-
- return scs_subscribe(c,buf);
-}
-
-extern guint8* scs_subscribe_float(SCS_collection* c, float f) {
- static guint8 buf[SCS_SMALL_SIZE];
-
- g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%f", f);
-
- return scs_subscribe(c,buf);
-}
-
/***************************************************************************
* AVPs & Co.
***************************************************************************
* @avpl: a pointer to the level of debugging of facility "avpl"
* @avpl_op: a pointer to the level of debugging of facility "avpl_op"
*
- * (If enabled set's up the debug facilities for the avp library.
+ * If enabled set's up the debug facilities for the avp library.
*
**/
extern void setup_avp_debug(FILE* fp, int* general, int* avp, int* avp_op, int* avpl, int* avpl_op) {
**/
extern void avp_init(void) {
+ if (avp_strings) destroy_scs_collection(avp_strings);
avp_strings = scs_init();
-
- if ( avp_chunk ) {
- g_mem_chunk_destroy(avp_chunk);
- }
-
+ if ( avp_chunk ) g_mem_chunk_destroy(avp_chunk);
avp_chunk = g_mem_chunk_new("avp_chunk", sizeof(any_avp_type),
AVP_CHUNK_SIZE, G_ALLOC_AND_FREE);
* Return value: a pointer to the newly created avp.
*
**/
-extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) {
+extern AVP* new_avp_from_finfo(const gchar* name, field_info* finfo) {
AVP* new = g_mem_chunk_alloc(avp_chunk);
- guint8* value;
-
+ gchar* value;
+
new->n = scs_subscribe(avp_strings, name);
- if (finfo->value.ftype->get_value_integer) {
- value = scs_subscribe_int(avp_strings, fvalue_get_integer(&finfo->value));
-#ifdef _AVP_DEBUGGING
- dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from integer: %s",value);
-#endif
- } else if (finfo->value.ftype->val_to_string_repr) {
+ if (finfo->value.ftype->val_to_string_repr) {
value = scs_subscribe(avp_strings, fvalue_to_string_repr(&finfo->value,FTREPR_DISPLAY,NULL));
#ifdef _AVP_DEBUGGING
dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from string: %s",value);
-#endif
- } else if (finfo->value.ftype->get_value_floating) {
- value = scs_subscribe_float(avp_strings, (float) fvalue_get_floating(&finfo->value));
-#ifdef _AVP_DEBUGGING
- dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from float: %s",value);
#endif
} else {
#ifdef _AVP_DEBUGGING
* Return value: a pointer to the newly created avp.
*
**/
-extern AVP* new_avp(guint8* name, guint8* value, guint8 o) {
+extern AVP* new_avp(const gchar* name, const gchar* value, gchar o) {
AVP* new = g_mem_chunk_alloc(avp_chunk);
new->n = scs_subscribe(avp_strings, name);
return new;
}
-
-extern void rename_avp(AVP* avp, guint8* name) {
- guint8* s = avp->n;
- avp->n = scs_subscribe(avp_strings,name);
- scs_unsubscribe(avp_strings,s);
-}
-
/**
* new_avpl:
* @name: the name the avpl will have.
* Return value: a pointer to the newly created avpl.
*
**/
-extern AVPL* new_avpl(guint8* name) {
+extern AVPL* new_avpl(const gchar* name) {
AVPL* new_avpl = g_mem_chunk_alloc(avp_chunk);
#ifdef _AVP_DEBUGGING
dbg_print(dbg_avpl_op,7,dbg_fp,"new_avpl: %X name=%s",new_avpl,name);
#endif
- new_avpl->name = scs_subscribe(avp_strings, name);
+ new_avpl->name = name ? scs_subscribe(avp_strings, name) : scs_subscribe(avp_strings, "");
new_avpl->len = 0;
new_avpl->null.avp = NULL;
new_avpl->null.next = &new_avpl->null;
return new_avpl;
}
-extern void rename_avpl(AVPL* avpl, guint8* name) {
+extern void rename_avpl(AVPL* avpl, gchar* name) {
scs_unsubscribe(avp_strings,avpl->name);
avpl->name = scs_subscribe(avp_strings,name);
}
* Return value: a pointer to the next matching avp if there's one, else NULL.
*
**/
-extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie) {
+extern AVP* get_avp_by_name(AVPL* avpl, gchar* name, void** cookie) {
AVPN* curr;
AVPN* start = (AVPN*) *cookie;
* Return value: a pointer to extracted avp if there's one, else NULL.
*
**/
-extern AVP* extract_avp_by_name(AVPL* avpl, guint8* name) {
+extern AVP* extract_avp_by_name(AVPL* avpl, gchar* name) {
AVPN* curr;
AVP* avp = NULL;
* Return value: a pointer to the newly allocated string.
*
**/
-guint8* avpl_to_str(AVPL* avpl) {
+gchar* avpl_to_str(AVPL* avpl) {
AVPN* c;
GString* s = g_string_new("");
- guint8* avp_s;
- guint8* r;
+ gchar* avp_s;
+ gchar* r;
for(c=avpl->null.next; c->avp; c = c->next) {
avp_s = avp_to_str(c->avp);
- g_string_sprintfa(s," %s;",avp_s);
+ g_string_append_printf(s," %s;",avp_s);
g_free(avp_s);
}
return r;
}
-extern guint8* avpl_to_dotstr(AVPL* avpl) {
+extern gchar* avpl_to_dotstr(AVPL* avpl) {
AVPN* c;
GString* s = g_string_new("");
- guint8* avp_s;
- guint8* r;
+ gchar* avp_s;
+ gchar* r;
for(c=avpl->null.next; c->avp; c = c->next) {
avp_s = avp_to_str(c->avp);
- g_string_sprintfa(s," .%s;",avp_s);
+ g_string_append_printf(s," .%s;",avp_s);
g_free(avp_s);
}
extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) {
AVPN* cd = NULL;
AVPN* cs = NULL;
- gint c;
+ ptrdiff_t c;
AVP* copy;
#ifdef _AVP_DEBUGGING
while(cs->avp) {
if(cd->avp) {
- c = (guint) cd->avp->n - (guint) cs->avp->n;
+ c = ADDRDIFF(cd->avp->n,cs->avp->n);
} else {
c = -1;
}
* Return value: a pointer to the newly allocated string.
*
**/
-extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps) {
+extern AVPL* new_avpl_from_avpl(const gchar* name, AVPL* avpl, gboolean copy_avps) {
AVPL* newavpl = new_avpl(name);
void* cookie = NULL;
AVP* avp;
return newavpl;
}
-
-#define TRANS_NUM '-': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0'
-
-/* BROKEN, makes no sense right now */
-/* FIXME: Use subscribe/unsubscribe */
-#if 0
-static AVP* avp_transform(AVP* src, AVP* op) {
- unsigned int i;
- guint8 c;
-
- GString* replace_str = NULL;
- GString* num_str = NULL;
- GString* return_str = NULL;
- guint8* v;
- long num = 0;
-
- enum _tranf_state {
- START,
- IN_NUM,
- IN_REPLACE,
- END
- } state;
-
- state = START;
-
- for(i = 0; i < strlen(op->v); i++) {
- c= op->v[i];
-
- if (state == END) break;
-
- switch(state) {
- case START:
- switch(c) {
- case '{':
- num_str = g_string_new("");
- state = IN_NUM;
- continue;
- default:
- continue;
- };
- case IN_NUM:
- switch(c) {
- case TRANS_NUM:
- g_string_append_c(num_str,c);
- continue;
- case ':':
- num = strtol(num_str->str,NULL,10);
- g_string_free(num_str,TRUE);
- replace_str = g_string_new("");
- state = IN_REPLACE;
- continue;
- default:
- /* will ignore any char that is not a number */
- continue;
- };
- case IN_REPLACE:
- switch(c) {
- case '\\':
- continue;
- case '}':
- state = END;
- continue;
- default :
- g_string_append_c(replace_str,c);
- continue;
- }
- case END:
- /* it will never reach */
- continue;
- }
-
- }
-
- v = src->v;
-
- if (num > 0) {
- return_str = g_string_new(v);
- g_string_erase(return_str,0,num);
- g_string_prepend(return_str,replace_str->str);
- } else if (num < 0) {
- return_str = g_string_new(v);
- g_string_truncate(return_str,return_str->len+num);
- g_string_append(return_str,replace_str->str);
-
- } else {
- return_str = g_string_new(replace_str->str);
- }
-
- g_mem_chunk_free(avp_chunk,v);
- g_string_free(replace_str,TRUE);
-
- src->o = '=';
- src->v = return_str->str;
- g_string_free(return_str,FALSE);
-
- return src;
-}
-
-#endif
-
/**
* match_avp:
* @src: an src to be compared agains an "op" avp
* Return value: a pointer to the newly created avpl containing the
* matching avps.
**/
-extern AVPL* new_avpl_loose_match(guint8* name,
+extern AVPL* new_avpl_loose_match(const gchar* name,
AVPL* src,
AVPL* op,
gboolean copy_avps) {
AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name));
AVPN* co = NULL;
AVPN* cs = NULL;
- gint c;
+ ptrdiff_t c;
AVP* m;
AVP* copy;
}
- c = (guint) co->avp->n - (guint) cs->avp->n;
+ c = ADDRDIFF(co->avp->n, cs->avp->n);
if ( c > 0 ) {
if (co->avp) co = co->next;
* Return value: a pointer to the newly created avpl containing the
* matching avps.
**/
-extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean copy_avps) {
- AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name));
+extern AVPL* new_avpl_every_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) {
+ AVPL* newavpl;
AVPN* co = NULL;
AVPN* cs = NULL;
- gint c;
+ ptrdiff_t c;
AVP* m;
AVP* copy;
+ gboolean matches;
#ifdef _AVP_DEBUGGING
dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
#endif
+ if (src->len == 0) return NULL;
+
+ newavpl = new_avpl(scs_subscribe(avp_strings, name));
- gboolean matches = TRUE;
+ if (op->len == 0)
+ return newavpl;
+
+ matches = TRUE;
cs = src->null.next;
co = op->null.next;
break;
}
- c = (guint) co->avp->n - (guint) cs->avp->n;
+ c = ADDRDIFF(co->avp->n,cs->avp->n);
if ( c > 0 ) {
delete_avpl(newavpl,TRUE);
* Return value: a pointer to the newly created avpl containing the
* matching avps.
**/
-extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) {
+extern AVPL* new_avpl_exact_match(const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) {
AVPL* newavpl = new_avpl(name);
AVPN* co = NULL;
AVPN* cs = NULL;
- gint c;
+ ptrdiff_t c;
AVP* m;
- AVP* copy;
+ AVP* copy;
#ifdef _AVP_DEBUGGING
dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
#endif
+ if (op->len == 0)
+ return newavpl;
+
+ if (src->len == 0) {
+ delete_avpl(newavpl,FALSE);
+ return NULL;
+ }
+
cs = src->null.next;
co = op->null.next;
while(1) {
- c = (guint) co->avp->n - (guint) cs->avp->n;
+ c = ADDRDIFF(co->avp->n,cs->avp->n);
if ( c > 0 ) {
delete_avpl(newavpl,TRUE);
return NULL;
}
-extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) {
+extern AVPL* new_avpl_from_match(avpl_match_mode mode, const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) {
AVPL* avpl = NULL;
-
+
switch (mode) {
case AVPL_STRICT:
avpl = new_avpl_exact_match(name,src,op,copy_avps);
merge_avpl(avpl, op, copy_avps);
break;
}
-
- return avpl;
-}
-/**
- * new_avpl_transform:
- *
- * creates an empty avpl transformation
- *
- * Return value: a pointer to the newly created avpl transformation
- **/
-extern AVPL_Transf* new_avpl_transform(guint8* name, AVPL* mixed, avpl_match_mode match_mode, avpl_replace_mode replace_mode) {
- AVPL_Transf* t = g_malloc(sizeof(AVPL_Transf));
- AVP* avp;
-
- t->name = g_strdup(name);
- t->match = new_avpl("match");
- t->replace = new_avpl("replace");
- t->match_mode = match_mode;
- t->replace_mode = replace_mode;
- t->next = NULL;
- t->map = NULL;
-
- while (( avp = extract_first_avp(mixed) )) {
- if (*(avp->n) == '.') {
- rename_avp(avp,((avp->n)+1));
- insert_avp(t->replace, avp);
- } else {
- insert_avp(t->match, avp);
- }
- }
-
- return t;
+ return avpl;
}
-
/**
* delete_avpl_transform:
* @it: a pointer to the avpl transformation object
#endif
for ( ; op ; op = op->next) {
-
+
avpl = new_avpl_from_match(op->match_mode, src->name,src, op->match, TRUE);
if (avpl) {
*
* Return value: a pointer to the newly created loal.
**/
-extern LoAL* new_loal(guint8* name) {
+extern LoAL* new_loal(const gchar* name) {
LoAL* new_loal = g_mem_chunk_alloc(avp_chunk);
if (! name) {
new_loal->null.avpl = NULL;
new_loal->null.next = &new_loal->null;
new_loal->null.prev = &new_loal->null;
-
+ new_loal->len = 0;
return new_loal;
}
loal->null.prev->next = node;
loal->null.prev = node;
+ loal->len++;
}
* load_loal_error:
* Used by loal_from_file to handle errors while loading.
**/
-void load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, guint8* fmt, ...) {
+static LoAL* load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, const gchar* fmt, ...) {
va_list list;
- guint8* desc;
-
+ gchar* desc;
+ LoAL* ret = NULL;
+ gchar* err;
va_start( list, fmt );
desc = g_strdup_vprintf(fmt, list);
va_end( list );
+
+ err = g_strdup_printf("Error Loading LoAL from file: in %s at line: %i, %s",loal->name,linenum,desc);
+ ret = new_loal(err);
+
+ g_free(desc);
+ g_free(err);
+
if (fp) fclose(fp);
if (loal) delete_loal(loal,TRUE,TRUE);
if (curr) delete_avpl(curr,TRUE);
- g_warning("Error Loading LoAL from file: at line: %i, %s",linenum,desc);
- g_free(desc);
-
- return;
+ return ret;
}
-/* the maximum lenght allowed for a line */
+/* the maximum length allowed for a line */
#define MAX_ITEM_LEN 8192
/* this two ugly things are used for tokenizing */
* Return value: if successful a pointer to the new populated loal, else NULL.
*
**/
-extern LoAL* loal_from_file(guint8* filename) {
- FILE *fp;
- guint8 c;
+extern LoAL* loal_from_file(gchar* filename) {
+ FILE *fp = NULL;
+ gchar c;
int i = 0;
guint32 linenum = 1;
- guint8 name[MAX_ITEM_LEN];
- guint8 value[MAX_ITEM_LEN];
- guint8 op = '?';
+ gchar linenum_buf[MAX_ITEM_LEN];
+ gchar name[MAX_ITEM_LEN];
+ gchar value[MAX_ITEM_LEN];
+ gchar op = '?';
LoAL *loal = new_loal(filename);
AVPL* curr = NULL;
AVP* avp;
#ifndef _WIN32
if (! getuid()) {
- g_warning( "MATE Will not run as root");
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"MATE Will not run as root");
}
#endif
state = START;
- if (( fp = fopen(filename,"r") )) {
- while(( c = (guint8) fgetc(fp) )){
+ if (( fp = ws_fopen(filename,"r") )) {
+ while(( c = (gchar) fgetc(fp) )){
if ( feof(fp) ) {
if ( ferror(fp) ) {
- load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename);
- return NULL;
+ report_read_failure(filename,errno);
+ return load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename);
}
break;
}
}
if ( i >= MAX_ITEM_LEN - 1 ) {
- load_loal_error(fp,loal,curr,linenum,"Maximum item lenght exceeded");
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"Maximum item length exceeded");
}
switch(state) {
i = 0;
name[i++] = c;
name[i] = '\0';
-
- curr = new_avpl("");
+ g_snprintf(linenum_buf,sizeof(linenum_buf),"%s:%u",filename,linenum);
+ curr = new_avpl(linenum_buf);
continue;
case '#':
state = MY_IGNORE;
continue;
default:
- load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
}
case BEFORE_NAME:
i = 0;
state = START;
continue;
default:
- load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
}
case IN_NAME:
switch (c) {
name[i++] = c;
continue;
case '\n':
- load_loal_error(fp,loal,curr,linenum,"operator expected found new line");
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"operator expected found new line");
default:
- load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c);
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c);
}
case IN_VALUE:
switch (c) {
}
continue;
case '\n':
- load_loal_error(fp,loal,curr,linenum,"';' expected found new line");
- return NULL;
+ return load_loal_error(fp,loal,curr,linenum,"';' expected found new line");
default:
value[i++] = c;
continue;
return loal;
} else {
- load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename);
- return NULL;
+ report_open_failure(filename,errno,FALSE);
+ return load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename);
}
}