(root)/
gettext-0.22.4/
libtextstyle/
lib/
glib/
glist.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 2006-2019 Free Software Foundation, Inc.
       3   *
       4   * This file is not part of the GNU gettext program, but is used with
       5   * GNU gettext.
       6   *
       7   * The original copyright notice is as follows:
       8   */
       9  
      10  /* GLIB - Library of useful routines for C programming
      11   * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
      12   *
      13   * This library is free software; you can redistribute it and/or
      14   * modify it under the terms of the GNU Lesser General Public
      15   * License as published by the Free Software Foundation; either
      16   * version 2 of the License, or (at your option) any later version.
      17   *
      18   * This library is distributed in the hope that it will be useful,
      19   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      20   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
      21   * Lesser General Public License for more details.
      22   *
      23   * You should have received a copy of the GNU Lesser General Public
      24   * License along with this library; if not, write to the
      25   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      26   * Boston, MA 02111-1307, USA.
      27   */
      28  
      29  /*
      30   * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      31   * file for a list of people on the GLib Team.  See the ChangeLog
      32   * files for a list of changes.  These files are distributed with
      33   * GLib at ftp://ftp.gtk.org/pub/gtk/. 
      34   */
      35  
      36  /*
      37   * Modified by Bruno Haible for use as a gnulib module.
      38   */
      39  
      40  /* 
      41   * MT safe
      42   */
      43  
      44  #include "config.h"
      45  
      46  #include "glib.h"
      47  #if 0
      48  #include "galias.h"
      49  #endif
      50  
      51  
      52  #if 0
      53  void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
      54  void g_list_pop_allocator  (void)           { /* present for binary compat only */ }
      55  #endif
      56  
      57  #define _g_list_alloc()         g_slice_new (GList)
      58  #define _g_list_alloc0()        g_slice_new0 (GList)
      59  #define _g_list_free1(list)     g_slice_free (GList, list)
      60  
      61  #if 0
      62  
      63  GList*
      64  g_list_alloc (void)
      65  {
      66    return _g_list_alloc0 ();
      67  }
      68  
      69  #endif
      70  
      71  void
      72  g_list_free (GList *list)
      73  {
      74    while (list)
      75      {
      76        GList *n = list->next;
      77        g_slice_free (GList, list);
      78        list = n;
      79      }
      80  }
      81  
      82  #if 0
      83  
      84  void
      85  g_list_free_1 (GList *list)
      86  {
      87    _g_list_free1 (list);
      88  }
      89  
      90  #endif
      91  
      92  GList*
      93  g_list_append (GList	*list,
      94  	       gpointer	 data)
      95  {
      96    GList *new_list;
      97    GList *last;
      98    
      99    new_list = _g_list_alloc ();
     100    new_list->data = data;
     101    new_list->next = NULL;
     102    
     103    if (list)
     104      {
     105        last = g_list_last (list);
     106        /* g_assert (last != NULL); */
     107        last->next = new_list;
     108        new_list->prev = last;
     109  
     110        return list;
     111      }
     112    else
     113      {
     114        new_list->prev = NULL;
     115        return new_list;
     116      }
     117  }
     118  
     119  GList*
     120  g_list_prepend (GList	 *list,
     121  		gpointer  data)
     122  {
     123    GList *new_list;
     124    
     125    new_list = _g_list_alloc ();
     126    new_list->data = data;
     127    new_list->next = list;
     128    
     129    if (list)
     130      {
     131        new_list->prev = list->prev;
     132        if (list->prev)
     133  	list->prev->next = new_list;
     134        list->prev = new_list;
     135      }
     136    else
     137      new_list->prev = NULL;
     138    
     139    return new_list;
     140  }
     141  
     142  #if 0
     143  
     144  GList*
     145  g_list_insert (GList	*list,
     146  	       gpointer	 data,
     147  	       gint	 position)
     148  {
     149    GList *new_list;
     150    GList *tmp_list;
     151    
     152    if (position < 0)
     153      return g_list_append (list, data);
     154    else if (position == 0)
     155      return g_list_prepend (list, data);
     156    
     157    tmp_list = g_list_nth (list, position);
     158    if (!tmp_list)
     159      return g_list_append (list, data);
     160    
     161    new_list = _g_list_alloc ();
     162    new_list->data = data;
     163    new_list->prev = tmp_list->prev;
     164    if (tmp_list->prev)
     165      tmp_list->prev->next = new_list;
     166    new_list->next = tmp_list;
     167    tmp_list->prev = new_list;
     168    
     169    if (tmp_list == list)
     170      return new_list;
     171    else
     172      return list;
     173  }
     174  
     175  GList*
     176  g_list_insert_before (GList   *list,
     177  		      GList   *sibling,
     178  		      gpointer data)
     179  {
     180    if (!list)
     181      {
     182        list = g_list_alloc ();
     183        list->data = data;
     184        g_return_val_if_fail (sibling == NULL, list);
     185        return list;
     186      }
     187    else if (sibling)
     188      {
     189        GList *node;
     190  
     191        node = _g_list_alloc ();
     192        node->data = data;
     193        node->prev = sibling->prev;
     194        node->next = sibling;
     195        sibling->prev = node;
     196        if (node->prev)
     197  	{
     198  	  node->prev->next = node;
     199  	  return list;
     200  	}
     201        else
     202  	{
     203  	  g_return_val_if_fail (sibling == list, node);
     204  	  return node;
     205  	}
     206      }
     207    else
     208      {
     209        GList *last;
     210  
     211        last = list;
     212        while (last->next)
     213  	last = last->next;
     214  
     215        last->next = _g_list_alloc ();
     216        last->next->data = data;
     217        last->next->prev = last;
     218        last->next->next = NULL;
     219  
     220        return list;
     221      }
     222  }
     223  
     224  GList *
     225  g_list_concat (GList *list1, GList *list2)
     226  {
     227    GList *tmp_list;
     228    
     229    if (list2)
     230      {
     231        tmp_list = g_list_last (list1);
     232        if (tmp_list)
     233  	tmp_list->next = list2;
     234        else
     235  	list1 = list2;
     236        list2->prev = tmp_list;
     237      }
     238    
     239    return list1;
     240  }
     241  
     242  GList*
     243  g_list_remove (GList	     *list,
     244  	       gconstpointer  data)
     245  {
     246    GList *tmp;
     247    
     248    tmp = list;
     249    while (tmp)
     250      {
     251        if (tmp->data != data)
     252  	tmp = tmp->next;
     253        else
     254  	{
     255  	  if (tmp->prev)
     256  	    tmp->prev->next = tmp->next;
     257  	  if (tmp->next)
     258  	    tmp->next->prev = tmp->prev;
     259  	  
     260  	  if (list == tmp)
     261  	    list = list->next;
     262  	  
     263  	  _g_list_free1 (tmp);
     264  	  
     265  	  break;
     266  	}
     267      }
     268    return list;
     269  }
     270  
     271  GList*
     272  g_list_remove_all (GList	*list,
     273  		   gconstpointer data)
     274  {
     275    GList *tmp = list;
     276  
     277    while (tmp)
     278      {
     279        if (tmp->data != data)
     280  	tmp = tmp->next;
     281        else
     282  	{
     283  	  GList *next = tmp->next;
     284  
     285  	  if (tmp->prev)
     286  	    tmp->prev->next = next;
     287  	  else
     288  	    list = next;
     289  	  if (next)
     290  	    next->prev = tmp->prev;
     291  
     292  	  _g_list_free1 (tmp);
     293  	  tmp = next;
     294  	}
     295      }
     296    return list;
     297  }
     298  
     299  #endif
     300  
     301  static inline GList*
     302  _g_list_remove_link (GList *list,
     303  		     GList *link)
     304  {
     305    if (link)
     306      {
     307        if (link->prev)
     308  	link->prev->next = link->next;
     309        if (link->next)
     310  	link->next->prev = link->prev;
     311        
     312        if (link == list)
     313  	list = list->next;
     314        
     315        link->next = NULL;
     316        link->prev = NULL;
     317      }
     318    
     319    return list;
     320  }
     321  
     322  #if 0
     323  
     324  GList*
     325  g_list_remove_link (GList *list,
     326  		    GList *link)
     327  {
     328    return _g_list_remove_link (list, link);
     329  }
     330  
     331  #endif
     332  
     333  GList*
     334  g_list_delete_link (GList *list,
     335  		    GList *link)
     336  {
     337    list = _g_list_remove_link (list, link);
     338    _g_list_free1 (link);
     339  
     340    return list;
     341  }
     342  
     343  #if 0
     344  
     345  GList*
     346  g_list_copy (GList *list)
     347  {
     348    GList *new_list = NULL;
     349  
     350    if (list)
     351      {
     352        GList *last;
     353  
     354        new_list = _g_list_alloc ();
     355        new_list->data = list->data;
     356        new_list->prev = NULL;
     357        last = new_list;
     358        list = list->next;
     359        while (list)
     360  	{
     361  	  last->next = _g_list_alloc ();
     362  	  last->next->prev = last;
     363  	  last = last->next;
     364  	  last->data = list->data;
     365  	  list = list->next;
     366  	}
     367        last->next = NULL;
     368      }
     369  
     370    return new_list;
     371  }
     372  
     373  GList*
     374  g_list_reverse (GList *list)
     375  {
     376    GList *last;
     377    
     378    last = NULL;
     379    while (list)
     380      {
     381        last = list;
     382        list = last->next;
     383        last->next = last->prev;
     384        last->prev = list;
     385      }
     386    
     387    return last;
     388  }
     389  
     390  GList*
     391  g_list_nth (GList *list,
     392  	    guint  n)
     393  {
     394    while ((n-- > 0) && list)
     395      list = list->next;
     396    
     397    return list;
     398  }
     399  
     400  GList*
     401  g_list_nth_prev (GList *list,
     402  		 guint  n)
     403  {
     404    while ((n-- > 0) && list)
     405      list = list->prev;
     406    
     407    return list;
     408  }
     409  
     410  gpointer
     411  g_list_nth_data (GList     *list,
     412  		 guint      n)
     413  {
     414    while ((n-- > 0) && list)
     415      list = list->next;
     416    
     417    return list ? list->data : NULL;
     418  }
     419  
     420  GList*
     421  g_list_find (GList         *list,
     422  	     gconstpointer  data)
     423  {
     424    while (list)
     425      {
     426        if (list->data == data)
     427  	break;
     428        list = list->next;
     429      }
     430    
     431    return list;
     432  }
     433  
     434  GList*
     435  g_list_find_custom (GList         *list,
     436  		    gconstpointer  data,
     437  		    GCompareFunc   func)
     438  {
     439    g_return_val_if_fail (func != NULL, list);
     440  
     441    while (list)
     442      {
     443        if (! func (list->data, data))
     444  	return list;
     445        list = list->next;
     446      }
     447  
     448    return NULL;
     449  }
     450  
     451  
     452  gint
     453  g_list_position (GList *list,
     454  		 GList *link)
     455  {
     456    gint i;
     457  
     458    i = 0;
     459    while (list)
     460      {
     461        if (list == link)
     462  	return i;
     463        i++;
     464        list = list->next;
     465      }
     466  
     467    return -1;
     468  }
     469  
     470  gint
     471  g_list_index (GList         *list,
     472  	      gconstpointer  data)
     473  {
     474    gint i;
     475  
     476    i = 0;
     477    while (list)
     478      {
     479        if (list->data == data)
     480  	return i;
     481        i++;
     482        list = list->next;
     483      }
     484  
     485    return -1;
     486  }
     487  
     488  #endif
     489  
     490  GList*
     491  g_list_last (GList *list)
     492  {
     493    if (list)
     494      {
     495        while (list->next)
     496  	list = list->next;
     497      }
     498    
     499    return list;
     500  }
     501  
     502  #if 0
     503  
     504  GList*
     505  g_list_first (GList *list)
     506  {
     507    if (list)
     508      {
     509        while (list->prev)
     510  	list = list->prev;
     511      }
     512    
     513    return list;
     514  }
     515  
     516  guint
     517  g_list_length (GList *list)
     518  {
     519    guint length;
     520    
     521    length = 0;
     522    while (list)
     523      {
     524        length++;
     525        list = list->next;
     526      }
     527    
     528    return length;
     529  }
     530  
     531  void
     532  g_list_foreach (GList	 *list,
     533  		GFunc	  func,
     534  		gpointer  user_data)
     535  {
     536    while (list)
     537      {
     538        GList *next = list->next;
     539        (*func) (list->data, user_data);
     540        list = next;
     541      }
     542  }
     543  
     544  static GList*
     545  g_list_insert_sorted_real (GList    *list,
     546  			   gpointer  data,
     547  			   GFunc     func,
     548  			   gpointer  user_data)
     549  {
     550    GList *tmp_list = list;
     551    GList *new_list;
     552    gint cmp;
     553  
     554    g_return_val_if_fail (func != NULL, list);
     555    
     556    if (!list) 
     557      {
     558        new_list = _g_list_alloc0 ();
     559        new_list->data = data;
     560        return new_list;
     561      }
     562    
     563    cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
     564  
     565    while ((tmp_list->next) && (cmp > 0))
     566      {
     567        tmp_list = tmp_list->next;
     568  
     569        cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
     570      }
     571  
     572    new_list = _g_list_alloc0 ();
     573    new_list->data = data;
     574  
     575    if ((!tmp_list->next) && (cmp > 0))
     576      {
     577        tmp_list->next = new_list;
     578        new_list->prev = tmp_list;
     579        return list;
     580      }
     581     
     582    if (tmp_list->prev)
     583      {
     584        tmp_list->prev->next = new_list;
     585        new_list->prev = tmp_list->prev;
     586      }
     587    new_list->next = tmp_list;
     588    tmp_list->prev = new_list;
     589   
     590    if (tmp_list == list)
     591      return new_list;
     592    else
     593      return list;
     594  }
     595  
     596  GList*
     597  g_list_insert_sorted (GList        *list,
     598  		      gpointer      data,
     599  		      GCompareFunc  func)
     600  {
     601    return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
     602  }
     603  
     604  GList*
     605  g_list_insert_sorted_with_data (GList            *list,
     606  				gpointer          data,
     607  				GCompareDataFunc  func,
     608  				gpointer          user_data)
     609  {
     610    return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
     611  }
     612  
     613  static GList *
     614  g_list_sort_merge (GList     *l1, 
     615  		   GList     *l2,
     616  		   GFunc     compare_func,
     617  		   gpointer  user_data)
     618  {
     619    GList list, *l, *lprev;
     620    gint cmp;
     621  
     622    l = &list; 
     623    lprev = NULL;
     624  
     625    while (l1 && l2)
     626      {
     627        cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
     628  
     629        if (cmp <= 0)
     630          {
     631  	  l->next = l1;
     632  	  l1 = l1->next;
     633          } 
     634        else 
     635  	{
     636  	  l->next = l2;
     637  	  l2 = l2->next;
     638          }
     639        l = l->next;
     640        l->prev = lprev; 
     641        lprev = l;
     642      }
     643    l->next = l1 ? l1 : l2;
     644    l->next->prev = l;
     645  
     646    return list.next;
     647  }
     648  
     649  static GList* 
     650  g_list_sort_real (GList    *list,
     651  		  GFunc     compare_func,
     652  		  gpointer  user_data)
     653  {
     654    GList *l1, *l2;
     655    
     656    if (!list) 
     657      return NULL;
     658    if (!list->next) 
     659      return list;
     660    
     661    l1 = list; 
     662    l2 = list->next;
     663  
     664    while ((l2 = l2->next) != NULL)
     665      {
     666        if ((l2 = l2->next) == NULL) 
     667  	break;
     668        l1 = l1->next;
     669      }
     670    l2 = l1->next; 
     671    l1->next = NULL; 
     672  
     673    return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
     674  			    g_list_sort_real (l2, compare_func, user_data),
     675  			    compare_func,
     676  			    user_data);
     677  }
     678  
     679  GList *
     680  g_list_sort (GList        *list,
     681  	     GCompareFunc  compare_func)
     682  {
     683    return g_list_sort_real (list, (GFunc) compare_func, NULL);
     684  			    
     685  }
     686  
     687  GList *
     688  g_list_sort_with_data (GList            *list,
     689  		       GCompareDataFunc  compare_func,
     690  		       gpointer          user_data)
     691  {
     692    return g_list_sort_real (list, (GFunc) compare_func, user_data);
     693  }
     694  
     695  #define __G_LIST_C__
     696  #include "galiasdef.c"
     697  #endif