Logo Search packages:      
Sourcecode: kbib version File versions  Download package

fields.cpp

/*
 * fields.c
 *
 * Copyright (c) Chris Putnam 2003-5
 *
 * Source code released under the GPL
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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; i<min_alloc; ++i ) {
                  newstr_init(&(info->tag[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; i<min_alloc; ++i ) {
                  newstr_init(&(info->tag[i]));
                  newstr_init(&(info->data[i]));
            }
      }
      found = 0;
      for ( i=0; i<info->nfields && !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; i<info->maxfields; ++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; i<info->nfields && found==-1; ++i ) {
            if ( (level==-1 || level==info->level[i]) &&
                 strsearch( info->tag[i].data, searchtag )==info->tag[i].data ) {
                  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_maxlevel( fields *info )
{
      int i, max = 0;
      for ( i=0; i<info->nfields; ++i ) {
            if ( info->level[i]>max ) max = info->level[i];
      }
      return max;
}

Generated by  Doxygen 1.6.0   Back to index