/* * fields.c * * Copyright (c) Chris Putnam 2003-2010 * * Source code released under the GPL * */ #include #include #include #include "strsearch.h" #include "fields.h" int fields_add( fields *info, char *tag, char *data, int level ) { newstr *newtags, *newdata; int *newused, *newlevel; int min_alloc = 20, i, found; if ( !tag || !data ) return 1; if ( info->maxfields==0 ){ info->tag = (newstr*)malloc( sizeof(newstr) * min_alloc ); info->data= (newstr*)malloc( sizeof(newstr) * min_alloc ); info->used= (int*) malloc( sizeof(int) * min_alloc ); info->level=(int*) malloc( sizeof(int) * min_alloc ); if ( !info->tag || !info->data || !info->used || !info->level ){ if ( info->tag ) free( info->tag ); if ( info->data ) free( info->data ); if ( info->used ) free( info->used ); if ( info->level ) free( info->level ); return 0; } info->maxfields = min_alloc; info->nfields = 0; for ( i=0; itag[i])); newstr_init(&(info->data[i])); } } else if ( info->nfields >= info->maxfields ){ min_alloc = info->maxfields * 2; newtags = (newstr*) realloc( info->tag, sizeof(newstr) * min_alloc ); newdata = (newstr*) realloc( info->data, sizeof(newstr) * min_alloc ); newused = (int*) realloc( info->used, sizeof(int) * min_alloc ); newlevel= (int*) realloc( info->level, sizeof(int) * min_alloc ); if ( !newtags || !newdata || !newused || !newlevel ) { if ( newtags ) info->tag=newtags; if ( newdata ) info->data=newdata; if ( newused ) info->used=newused; if ( newlevel ) info->level=newlevel; return 0; } info->tag = newtags; info->data = newdata; info->used = newused; info->level = newlevel; info->maxfields = min_alloc; for ( i=info->nfields; itag[i])); newstr_init(&(info->data[i])); } } found = 0; for ( i=0; infields && !found; ++i ) { if ( info->level[i]==level && !strcasecmp( info->tag[i].data, tag ) && !strcasecmp( info->data[i].data, data ) ) found=1; } if ( !found ) { newstr_strcpy( &(info->tag[info->nfields]), tag ); newstr_strcpy( &(info->data[info->nfields]), data ); info->used[ info->nfields ] = 0; info->level[ info->nfields ] = level; info->nfields++; } return 1; } int fields_add_tagsuffix( fields *info, char *tag, char *suffix, char *data, int level ) { char *buf; int len, ret; len = strlen( tag ) + strlen( suffix ) + 1; buf = ( char * ) malloc( sizeof(char)*len ); if ( !buf ) return 0; strcpy( buf, tag ); strcat( buf, suffix ); ret = fields_add( info, buf, data, level ); free( buf ); return ret; } fields* fields_new( void ) { fields *info = ( fields * ) malloc( sizeof( fields ) ); if ( info ) fields_init( info ); return info; } void fields_init( fields *info ) { info->used = NULL; info->level = NULL; info->tag = NULL; info->data = NULL; info->maxfields = info->nfields = 0; } void fields_free( fields *info ) { int i; for (i=0; imaxfields; ++i) { newstr_free( &(info->tag[i]) ); newstr_free( &(info->data[i]) ); } if ( info->tag ) free( info->tag ); if ( info->data ) free( info->data ); if ( info->used ) free( info->used ); if ( info->level ) free( info->level ); fields_init( info ); } int fields_find( fields *info, char *searchtag, int level ) { int i, found = -1; for ( i=0; infields && found==-1; ++i ) { if ( (level==-1 || level==info->level[i]) && !strcasecmp( info->tag[i].data, searchtag ) ) { found = i; /* if there is no data for the tag, mark as unfound */ /* but set "used" so noise is suppressed */ if ( info->data[i].len==0 ) { found=-1; info->used[i] = 1; } } } return found; } int fields_find_firstof( fields *info, char *tags[], int ntags, int level ) { int i=0, found = -1; while ( infields; ++i ) { if ( info->level[i]>max ) max = info->level[i]; } return max; } void fields_clearused( fields *info ) { int i; for ( i=0; infields; ++i ) info->used[i] = 0; } void fields_setused( fields *info, int n ) { if ( n < info->nfields ) info->used[n] = 1; } void fields_replace_or_add( fields *info, char *tag, char *data, int level ) { int n = fields_find( info, tag, level ); if ( n==-1 ) fields_add( info, tag, data, level ); else newstr_strcpy( &(info->data[n]), data ); }