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

string_list.c

Go to the documentation of this file.
/*
 * jclassinfo
 * Copyright (C) 2003  Nicos Panayides
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Nicos Panayides
 * anarxia@gmx.net
 *
 * $Id: string_list.c,v 1.6 2003/12/08 11:10:52 anarxia Exp $
 */

/** @file string_list.c
* @brief Functions for string sets.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "string_list.h"

/* String list node.
* A node in a string list. Not intented to be used directly.
*/
struct string_node {
      char* string;
      int flag;
      struct string_node* next;
};

/* Creates a new string list.
* Returns a pointer to a newly allocated new string list
*/
StringList* string_list_new()
{
      StringList *list;
      
      list = (StringList*) malloc(sizeof(StringList));
      list->head = NULL;
      
      return list;
}

/**
* free_string_list
* @list: the list to free
*
* Frees the given list.
*/
00064 void string_list_free(StringList *list)
{
      struct string_node* node;
      struct string_node* next_node;
      
      node = list->head;
      while(node != NULL) {
            next_node = node->next;
                  
            if(node->string != NULL)
                  free(node->string);
                        
            free(node);       
            node = next_node;
      }
      free(list);
      return;
}

/**
* string_list_is_empty
* @list: The list to check
*
* Checks whether the given list is empty.
*
* Returns: 1 if empty, 0 otherwise.
*/
00091 int string_list_is_empty(StringList* list)
{
      return (list->head == NULL);
}

/**
* string_list_remove_first
* @list: The list containing the string.
* @flag: The flag of the string.
*
* Removes and returns the first string matching the given flag.
* If the string has more flags set the flag will be unset and
* the string will not be removed. String which have the
* IS_FINISHED_FLAG set will be ignored.
*
* Returns: A copy of the string allocated with malloc.
*/
00108 char* string_list_remove_first(StringList* list, int flag)
{
      struct string_node *curr, *prev;
      char* node_string;
      
      curr = list->head;
      prev = NULL;

      while(curr != NULL && (!(curr->flag & flag) || curr->flag & IS_FINISHED))
      {
            prev = curr;
            curr = curr->next;
      }

      if(curr == NULL)
            return NULL;
      
      curr->flag &= ~flag;
      node_string = strdup(curr->string);

      if(!curr->flag)
      {
            if(curr == list->head)
                  list->head = curr->next;
            else
                  prev->next = curr->next;

            free(curr->string);
            free(curr);
      }
      return node_string;
}

/**
* string_list_add
* @list: The list to add the string.
* @new_string: The string to add.
* @flag: The flag for the string.
*
* If the string is already in the list it will not be added.
* If the string has other flags set, the given flag will also be set. 
*
* Returns: 1 if the string was added, 0 otherwise.
*/
00152 int string_list_add(StringList* list, const char* new_string, int flag)
{
      struct string_node* node;
      struct string_node* prev;
      struct string_node* next;
      
      if(new_string == NULL)
            return 0;
      
      next = list->head;
      prev = NULL;
      
      while(next != NULL && strcmp(next->string, new_string) < 0)
      {
            prev = next;
            next = next->next;
      }
            
      if((next == NULL) || strcmp(next->string, new_string))
      {
            node = (struct string_node*) malloc(sizeof(struct string_node));
            node->string = strdup(new_string);
            node->flag = flag;
            node->next = next;

            if(next == list->head)
                  list->head = node;
            else
                  prev->next = node;
      }
      else
      {
            /* if IS_LOCAL set remove IS_DEPENDENCY from flags */
            if(next->flag & IS_LOCAL)
                  flag &= ~IS_DEPENDENCY;
            
            flag &= ~(next->flag);

            if(!flag)
                  return 0;

            next->flag |= flag;
      }
      return 1;
}

/** string_list_remove
* @list: The list to remove the string from.
* @dead_string: The string to remove.
* @flag: The flag of the string to remove.
*
* Removes a string from the list. If the string has more flags set
* it will not be removed but the given flag will be unset.
*/
00206 void string_list_remove(StringList* list, const char* dead_string, int flag)
{
      struct string_node* prev;
      struct string_node* curr;
      
      if(dead_string == NULL)
            return;
      
      curr = list->head;
      prev = NULL;
      
      if(curr == NULL)
            return;
      
      while(curr != NULL && strcmp(curr->string, dead_string) < 0)
      {
            prev = curr;
            curr = curr->next;
      }
      if (curr == NULL)
            return;
      
      if(!strcmp(curr->string, dead_string))
      {
            curr->flag &= ~flag;
            if (!curr->flag)
            {
                  if(curr == list->head)
                  {
                        list->head = curr->next;
                        free(curr->string);
                        free(curr);
                  }
                  else
                  {
                        prev->next = curr->next;
                        free(curr->string);
                        free(curr);
                  }
            }
      }
}

/**
* string_list_remove_all
* @list: The list to remove the strings from.
* @flag: The flag to remove.
*
* Removes all strings matching the given flag.
* Any string that has additional flags will not be removed
* but it will have the given flag unset.
*/
00258 void string_list_remove_all(StringList* list, int flag)
{
      struct string_node* prev;
      struct string_node* curr;
      
      curr = list->head;
      prev = NULL;
      
      while(curr != NULL)
      {
            if(curr->flag & flag)
            {
                  curr->flag &= ~flag;
                  if (!curr->flag)
                  {
                        if(curr == list->head)
                        {
                              list->head = curr->next;
                              free(curr->string);
                              free(curr);
                              curr = list->head;
                              prev = NULL;
                        }
                        else
                        {
                              prev->next = curr->next;
                              free(curr->string);
                              free(curr);
                              curr = prev->next;
                        }
                  }
            }
            else
            {
                  prev = curr;
                  curr = curr->next;
            }
      }
}

/**
* string_list_print
* @outfile: The file to print the list to.
* @list: The list to print.
* @flag: The flag of the strings to print.
*
* Prints all strings in the list that have the given flag.
*/
00306 void string_list_print(FILE* outfile, StringList* list, int flag)
{
      struct string_node* node;
            
      node = list->head;
      
      while(node != NULL)
      {
            if (node->flag & flag)
                  fprintf(outfile,"%s\n", node->string);
            node = node->next;
      }     
}

/** 
* string_list_print_xml
* @outfile: The file to dump the list to.
* @list: The list to dump.
* @flag: The flag of the strings to print.
* 
* Prints all strings in the list the have the given flag as xml.
* The strings are printed one at every line.
*/
00329 void string_list_print_xml(FILE* outfile, StringList* list, int flag)
{
      struct string_node* node;
            
      node = list->head;
      
      while(node != NULL)
      {
            if (node->flag & flag)
                  fprintf(outfile,"<refentry>%s</refentry>\n", node->string);
            node = node->next;
      }     
}

/** @brief Returns whether a given string is in the list.
* @param list The list to search
* @param string The string to look for
*/
00347 int string_list_contains(StringList *list, const char *string, int flag)
{
      struct string_node* node;
      int compare;
      
      node = list->head;
      
      while(node != NULL)
      {
            compare = strcmp(node->string, string);
            
            if(compare == 0)
                  return (node->flag & flag);
            else if(compare > 0)
                  return 0;
            
            node = node->next;
      }
      
      return 0;   
}

Generated by  Doxygen 1.6.0   Back to index