Fix some "format not a string literal and no format arguments" warnings.
[obnox/wireshark/wip.git] / plugins / mate / mate_util.c
index 3ffc0c76ffc8225e6e22593752b60f1fac123136..39a0eb71d10f26417d97ab7b789747fe9a119c91 100644 (file)
@@ -2,12 +2,12 @@
 * 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)))
 
 
 /***************************************************************************
@@ -61,8 +52,8 @@
  * 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;
@@ -72,9 +63,10 @@ void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) {
        va_end( list );
 
        if (! where) {
-               g_message(debug_buffer);
+               g_message("%s", debug_buffer);
        } else {
                fputs(debug_buffer,where);
+               fputs("\n",where);
        }
 
 }
@@ -83,11 +75,10 @@ void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) {
 /***************************************************************************
  *  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:
@@ -100,7 +91,7 @@ void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) {
 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;
@@ -112,7 +103,7 @@ extern void destroy_scs_collection(SCS_collection* c) {
        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);
 }
 
@@ -120,19 +111,19 @@ extern SCS_collection* scs_init(void) {
        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;
@@ -151,22 +142,22 @@ extern SCS_collection* scs_init(void) {
  *
  * 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;
@@ -184,10 +175,10 @@ guint8* scs_subscribe(SCS_collection* c, guint8* s) {
                        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);
        }
 
@@ -202,20 +193,20 @@ guint8* scs_subscribe(SCS_collection* c, guint8* s) {
  * 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) {
@@ -224,8 +215,8 @@ void scs_unsubscribe(SCS_collection* c, guint8* s) {
                                chunk = c->mate_large;
                        } else {
                                chunk = c->mate_huge;
-                       } 
-                       
+                       }
+
                        g_mem_chunk_free(chunk,orig);
                        g_mem_chunk_free(c->ctrs,ip);
                }
@@ -233,7 +224,7 @@ void scs_unsubscribe(SCS_collection* c, guint8* s) {
                        (*ip)--;
                }
        } else {
-               g_warning("unsusbcribe: already deleted: '%s'?",s);
+               g_warning("unsusbcribe: not subscribed");
        }
 }
 
@@ -246,10 +237,10 @@ void scs_unsubscribe(SCS_collection* c, guint8* s) {
  * 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 );
@@ -257,22 +248,6 @@ extern guint8* scs_subscribe_printf(SCS_collection* c, guint8* fmt, ...) {
        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.
 ***************************************************************************
@@ -324,7 +299,7 @@ static int* dbg_avpl_op = &dbg_avpl_op_level;
  * @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) {
@@ -347,13 +322,10 @@ extern void setup_avp_debug(FILE* fp, int* general, int* avp, int* avp_op, int*
  **/
 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);
 
@@ -370,26 +342,16 @@ extern void avp_init(void) {
  * 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
@@ -421,7 +383,7 @@ extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) {
  * 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);
@@ -476,13 +438,6 @@ extern AVP* avp_copy(AVP* from) {
        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.
@@ -492,14 +447,14 @@ extern void rename_avp(AVP* avp, guint8* name) {
  * 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;
@@ -509,7 +464,7 @@ extern AVPL* new_avpl(guint8* name) {
        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);
 }
@@ -592,7 +547,7 @@ extern gboolean insert_avp(AVPL* avpl, AVP* avp) {
  * 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;
 
@@ -631,7 +586,7 @@ extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** 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;
 
@@ -818,15 +773,15 @@ extern AVP* get_next_avp(AVPL* avpl, void** cookie) {
  * 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);
        }
 
@@ -837,15 +792,15 @@ guint8* avpl_to_str(AVPL* avpl) {
        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);
        }
 
@@ -870,7 +825,7 @@ extern guint8* avpl_to_dotstr(AVPL* avpl) {
 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
@@ -883,7 +838,7 @@ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) {
        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;
                }
@@ -937,7 +892,7 @@ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) {
  * 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;
@@ -965,106 +920,6 @@ extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps) {
        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
@@ -1167,7 +1022,7 @@ extern AVP* match_avp(AVP* src, AVP* op) {
  * 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) {
@@ -1175,7 +1030,7 @@ extern AVPL* new_avpl_loose_match(guint8* name,
        AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name));
        AVPN* co = NULL;
        AVPN* cs = NULL;
-       gint  c;
+       ptrdiff_t c;
        AVP* m;
        AVP* copy;
 
@@ -1197,7 +1052,7 @@ extern AVPL* new_avpl_loose_match(guint8* name,
                }
 
 
-               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;
@@ -1245,19 +1100,26 @@ extern AVPL* new_avpl_loose_match(guint8* name,
  * 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;
@@ -1271,7 +1133,7 @@ extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean co
                        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);
@@ -1329,23 +1191,31 @@ extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean co
  * 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);
@@ -1392,9 +1262,9 @@ extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean cop
        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);
@@ -1410,42 +1280,10 @@ extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, A
                        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
@@ -1497,7 +1335,7 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) {
 #endif
 
        for ( ; op ; op = op->next) {
-               
+
                avpl = new_avpl_from_match(op->match_mode, src->name,src, op->match, TRUE);
 
                if (avpl) {
@@ -1544,7 +1382,7 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) {
  *
  * 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) {
@@ -1559,7 +1397,7 @@ extern LoAL* new_loal(guint8* 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;
 }
 
@@ -1584,6 +1422,7 @@ extern void loal_append(LoAL* loal, AVPL* avpl) {
 
        loal->null.prev->next = node;
        loal->null.prev = node;
+       loal->len++;
 }
 
 
@@ -1722,27 +1561,32 @@ extern void delete_loal(LoAL* loal, gboolean avpls_too, gboolean avps_too) {
  * 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 */
@@ -1767,14 +1611,15 @@ case '7': case '8': case '9': case '.'
  * 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;
@@ -1789,20 +1634,19 @@ extern LoAL* loal_from_file(guint8* filename) {
 
 #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;
                        }
@@ -1812,8 +1656,7 @@ extern LoAL* loal_from_file(guint8* filename) {
                        }
 
                        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) {
@@ -1841,15 +1684,14 @@ extern LoAL* loal_from_file(guint8* filename) {
                                                        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;
@@ -1873,8 +1715,7 @@ extern LoAL* loal_from_file(guint8* filename) {
                                                        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) {
@@ -1903,11 +1744,9 @@ extern LoAL* loal_from_file(guint8* filename) {
                                                                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) {
@@ -1927,8 +1766,7 @@ extern LoAL* loal_from_file(guint8* filename) {
                                                                }
                                                                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;
@@ -1940,7 +1778,7 @@ extern LoAL* loal_from_file(guint8* filename) {
                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);
        }
 }