~xubuntu-dev/libxfce4util/maverick

« back to all changes in this revision

Viewing changes to libxfce4util/xfce-rc-simple.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2008-07-06 10:58:49 UTC
  • mfrom: (1.2.11 upstream)
  • mto: (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080706105849-zetal1iaztbjbj6x
Tags: 4.4.2-3
* debian/control:
  - fixed typo in short description.                          closes: #489493
  - removed Martin Loschwitz from Uploaders.
  - updated standards version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: xfce-rc-simple.c 21094 2006-04-19 19:19:03Z benny $ */
 
1
/* $Id: xfce-rc-simple.c 24966 2007-02-13 10:16:28Z benny $ */
2
2
/*-
3
 
 * Copyright (c) 2003-2005 Benedikt Meurer <benny@xfce.org>
 
3
 * Copyright (c) 2003-2007 Benedikt Meurer <benny@xfce.org>
4
4
 * All rights reserved.
5
5
 *
6
6
 * This library is free software; you can redistribute it and/or
37
37
#include <unistd.h>
38
38
#endif
39
39
 
 
40
#include <libxfce4util/xfce-private.h>
40
41
#include <libxfce4util/xfce-rc-private.h>
 
42
#include <libxfce4util/libxfce4util-alias.h>
41
43
 
42
44
 
43
45
#ifndef PATH_MAX
57
59
typedef struct _LEntry LEntry;
58
60
typedef struct _Group  Group;
59
61
 
 
62
 
 
63
 
 
64
static Group*   simple_add_group  (XfceRcSimple *simple,
 
65
                                   const gchar  *name);
 
66
static Entry*   simple_add_entry  (XfceRcSimple *simple,
 
67
                                   const gchar  *key,
 
68
                                   const gchar  *value,
 
69
                                   const gchar  *locale);
 
70
static gboolean simple_parse_line (gchar        *line,
 
71
                                   gchar       **section,
 
72
                                   gchar       **key,
 
73
                                   gchar       **value,
 
74
                                   gchar       **locale);
 
75
static gchar*   simple_escape     (gchar        *buffer,
 
76
                                   gsize         size,
 
77
                                   const gchar  *string);
 
78
static gboolean simple_write      (XfceRcSimple *simple,
 
79
                                   const gchar  *filename);
 
80
static void     simple_entry_free (Entry        *entry);
 
81
static void     simple_group_free (Group        *group);
 
82
 
 
83
 
 
84
 
60
85
struct _XfceRcSimple
61
86
{
62
87
  XfceRc        __parent__;
63
88
 
64
89
  gboolean      shared_chunks;
65
 
  GMemChunk    *entry_chunk;
66
 
  GMemChunk    *lentry_chunk;
67
 
  GMemChunk    *group_chunk;
68
90
  GStringChunk *string_chunk;
69
91
 
70
92
  gchar        *filename;
77
99
  gboolean      readonly;
78
100
};
79
101
 
80
 
 
81
102
struct _Entry
82
103
{
83
104
  gchar  *key;
106
127
};
107
128
 
108
129
 
109
 
/* local prototypes */
110
 
static Group*   simple_add_group  (XfceRcSimple *simple,
111
 
                                                           const gchar  *name);
112
 
static Entry*   simple_add_entry  (XfceRcSimple *simple,
113
 
                                   const gchar  *key,
114
 
                                   const gchar  *value,
115
 
                                   const gchar  *locale);
116
 
static gboolean simple_parse_line (gchar        *line,
117
 
                                                           gchar       **section,
118
 
                                                           gchar       **key,
119
 
                                                           gchar       **value,
120
 
                                                           gchar       **locale);
121
 
static gchar*   simple_escape     (gchar        *buffer,
122
 
                                                           gsize         size,
123
 
                                                           const gchar  *string);
124
 
static gboolean simple_write      (XfceRcSimple *simple,
125
 
                                                           const gchar  *filename);
126
 
 
127
130
 
128
131
static Group*
129
 
simple_add_group (XfceRcSimple *simple, const gchar *name)
 
132
simple_add_group (XfceRcSimple *simple,
 
133
                  const gchar  *name)
130
134
{
131
135
  Group *group;
132
136
 
134
138
    if (strcmp (group->name, name) == 0)
135
139
      return group;
136
140
 
137
 
  group         = g_chunk_new (Group, simple->group_chunk);
 
141
  group         = _xfce_slice_new (Group);
138
142
  group->name   = g_string_chunk_insert (simple->string_chunk, name);
139
143
  group->efirst = NULL;
140
144
  group->elast  = NULL;
156
160
}
157
161
 
158
162
 
 
163
 
159
164
static Entry*
160
165
simple_add_entry (XfceRcSimple *simple,
161
 
                              const gchar  *key,
162
 
                          const gchar  *value,
163
 
                          const gchar  *locale)
 
166
                  const gchar  *key,
 
167
                  const gchar  *value,
 
168
                  const gchar  *locale)
164
169
{
165
170
  LEntry *lentry_before;
166
171
  LEntry *lentry;
196
201
      }
197
202
      /* why you annoying macro, will you stop borking libxfceutil? thanks. DO NOT DO THAT: g_return_val_if_fail (locale == NULL, NULL); */
198
203
 
199
 
      entry         = g_chunk_new (Entry, simple->entry_chunk);
 
204
      entry         = _xfce_slice_new (Entry);
200
205
      entry->key    = g_string_chunk_insert (simple->string_chunk, key);
201
206
      entry->value  = g_string_chunk_insert (simple->string_chunk, value);
202
207
      entry->lfirst = NULL;
222
227
    {
223
228
      /* overwrite existing value */
224
229
      if (G_LIKELY (strcmp (entry->value, value) != 0))
225
 
              entry->value = g_string_chunk_insert (simple->string_chunk, value);
 
230
        entry->value = g_string_chunk_insert (simple->string_chunk, value);
226
231
    }
227
232
  else
228
233
    {
253
258
      if (G_LIKELY (lentry == NULL))
254
259
        {
255
260
          /* create new localized entry */
256
 
          lentry         = g_chunk_new (LEntry, simple->lentry_chunk);
 
261
          lentry         = _xfce_slice_new (LEntry);
257
262
          lentry->locale = g_string_chunk_insert (simple->string_chunk, locale);
258
263
          lentry->value  = g_string_chunk_insert (simple->string_chunk, value);
259
264
 
292
297
}
293
298
 
294
299
 
 
300
 
295
301
static gboolean
296
302
simple_parse_line (gchar  *line,
297
303
                   gchar **section,
317
323
  if (*p == '[')
318
324
    {
319
325
      for (q = ++p; *q != '\0' && *q != ']'; ++q)
320
 
              ;
 
326
        ;
321
327
 
322
328
      if (G_LIKELY (*q == ']'))
323
329
        {
329
335
  else
330
336
    {
331
337
      for (q = p + 1; *q != '=' && *q != '\0'; ++q)
332
 
              ;
 
338
        ;
333
339
      if (G_UNLIKELY (*q != '='))
334
 
        return FALSE;
 
340
        return FALSE;
335
341
 
336
342
      r = q + 1;
337
343
 
338
344
      for (--q; g_ascii_isspace (*q); --q)
339
 
        ;
 
345
        ;
340
346
 
341
347
      if (G_UNLIKELY (q == p))
342
 
        return FALSE;
 
348
        return FALSE;
343
349
 
344
350
      if (*q == ']')
345
351
        {
423
429
}
424
430
 
425
431
 
 
432
 
426
433
static gchar*
427
434
simple_escape (gchar *buffer, gsize size, const gchar *string)
428
435
{
486
493
}
487
494
 
488
495
 
 
496
 
489
497
static gboolean
490
498
simple_write (XfceRcSimple *simple, const gchar *filename)
491
499
{
498
506
  fp = fopen (filename, "w");
499
507
  if (G_UNLIKELY (fp == NULL))
500
508
    {
501
 
      g_critical ("Unable to open file %s for writing: %s",
502
 
                  filename,
503
 
                  g_strerror (errno));
 
509
      g_critical ("Unable to open file %s for writing: %s", filename, g_strerror (errno));
504
510
      return FALSE;
505
511
    }
506
512
 
508
514
    {
509
515
      /* don't store empty groups */
510
516
      if (group->efirst == NULL)
511
 
              continue;
 
517
        continue;
512
518
 
513
519
      /* NULL_GROUP has no header */
514
520
      if (strcmp (group->name, NULL_GROUP) != 0)
515
 
        fprintf (fp, "[%s]\n", group->name);
 
521
        fprintf (fp, "[%s]\n", group->name);
516
522
 
517
523
      for (entry = group->efirst; entry != NULL; entry = entry->next)
518
 
        {
 
524
        {
519
525
          simple_escape (buffer, LINE_MAX, entry->value);
520
 
          fprintf (fp, "%s=%s\n", entry->key, buffer);
 
526
          fprintf (fp, "%s=%s\n", entry->key, buffer);
521
527
 
522
 
          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
523
 
                  {
 
528
          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
 
529
            {
524
530
              simple_escape (buffer, LINE_MAX, lentry->value);
525
 
              fprintf (fp, "%s[%s]=%s\n", entry->key, lentry->locale, buffer);
526
 
                  }
527
 
        }
 
531
              fprintf (fp, "%s[%s]=%s\n", entry->key, lentry->locale, buffer);
 
532
            }
 
533
        }
528
534
 
529
535
      fprintf (fp, "\n");
530
536
    }
531
537
 
532
538
  if (ferror (fp))
533
539
    {
534
 
      g_critical ("Unable to write to file %s: Unexpected internal error",
535
 
                              filename);
 
540
      g_critical ("Unable to write to file %s: Unexpected internal error", filename);
536
541
      fclose (fp);
537
542
      unlink (filename);
538
543
      return FALSE;
543
548
}
544
549
 
545
550
 
 
551
 
 
552
static void
 
553
simple_entry_free (Entry *entry)
 
554
{
 
555
  LEntry *lentry;
 
556
  LEntry *next;
 
557
 
 
558
  /* release all lentries */
 
559
  for (lentry = entry->lfirst; lentry != NULL; lentry = next)
 
560
    {
 
561
      /* determine the next lentry */
 
562
      next = lentry->next;
 
563
 
 
564
      /* release this lentry */
 
565
      _xfce_slice_free (LEntry, lentry);
 
566
    }
 
567
 
 
568
  /* release the entry */
 
569
  _xfce_slice_free (Entry, entry);
 
570
}
 
571
 
 
572
 
 
573
 
 
574
static void
 
575
simple_group_free (Group *group)
 
576
{
 
577
  Entry *entry;
 
578
  Entry *next;
 
579
 
 
580
  /* release all entries */
 
581
  for (entry = group->efirst; entry != NULL; entry = next)
 
582
    {
 
583
      /* determine the next entry */
 
584
      next = entry->next;
 
585
 
 
586
      /* release this entry */
 
587
      simple_entry_free (entry);
 
588
    }
 
589
 
 
590
  /* release the group */
 
591
  _xfce_slice_free (Group, group);
 
592
}
 
593
 
 
594
 
 
595
 
546
596
XfceRcSimple*
547
597
_xfce_rc_simple_new (XfceRcSimple *shared,
548
 
                     const gchar  *filename,
549
 
                     gboolean      readonly)
 
598
                     const gchar  *filename,
 
599
                     gboolean      readonly)
550
600
{
551
601
  XfceRcSimple *simple;
552
602
 
578
628
  if (shared != NULL)
579
629
    {
580
630
      simple->shared_chunks = TRUE;
581
 
      simple->entry_chunk   = shared->entry_chunk;
582
 
      simple->lentry_chunk  = shared->lentry_chunk;
583
 
      simple->group_chunk   = shared->group_chunk;
584
631
      simple->string_chunk  = shared->string_chunk;
585
632
    }
586
633
  else
587
634
    {
588
635
      simple->shared_chunks = FALSE;
589
 
      simple->entry_chunk   = g_mem_chunk_create (Entry, 128, G_ALLOC_ONLY);
590
 
      simple->lentry_chunk  = g_mem_chunk_create (LEntry, 256, G_ALLOC_ONLY);
591
 
      simple->group_chunk   = g_mem_chunk_create (Group, 32, G_ALLOC_ONLY);
592
636
      simple->string_chunk  = g_string_chunk_new (4096);
593
637
    }
594
638
 
602
646
}
603
647
 
604
648
 
 
649
 
605
650
gboolean
606
651
_xfce_rc_simple_parse (XfceRcSimple *simple)
607
652
{
613
658
  gchar   *key;
614
659
  FILE    *fp;
615
660
 
616
 
  g_return_val_if_fail (simple != NULL, FALSE);
617
 
  g_return_val_if_fail (simple->filename != NULL, FALSE);
 
661
  _xfce_return_val_if_fail (simple != NULL, FALSE);
 
662
  _xfce_return_val_if_fail (simple->filename != NULL, FALSE);
618
663
 
619
664
  readonly = xfce_rc_is_readonly (XFCE_RC (simple));
620
665
 
625
670
  while (fgets (line, LINE_MAX, fp) != NULL)
626
671
    {
627
672
      if (!simple_parse_line (line, &section, &key, &value, &locale))
628
 
              continue;
 
673
        continue;
629
674
 
630
675
      if (section != NULL)
631
 
        {
632
 
          simple->group = simple_add_group (simple, section);
633
 
          continue;
634
 
        }
 
676
        {
 
677
          simple->group = simple_add_group (simple, section);
 
678
          continue;
 
679
        }
635
680
 
636
681
      if (locale == NULL)
637
 
        {
638
 
          simple_add_entry (simple, key, value, NULL);
639
 
          continue;
640
 
        }
 
682
        {
 
683
          simple_add_entry (simple, key, value, NULL);
 
684
          continue;
 
685
        }
641
686
 
642
687
      if (XFCE_RC (simple)->locale == NULL)
643
 
        continue;
 
688
        continue;
644
689
 
645
690
      if (xfce_locale_match (XFCE_RC (simple)->locale, locale) > XFCE_LOCALE_NO_MATCH
646
691
          || !readonly)
655
700
}
656
701
 
657
702
 
 
703
 
658
704
void
659
705
_xfce_rc_simple_close (XfceRc *rc)
660
706
{
661
707
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
662
 
 
 
708
  Group        *group_next;
 
709
  Group        *group;
 
710
 
 
711
  /* release all memory allocated to the groups */
 
712
  for (group = simple->gfirst; group != NULL; group = group_next)
 
713
    {
 
714
      /* determine the next group */
 
715
      group_next = group->next;
 
716
 
 
717
      /* release this group */
 
718
      simple_group_free (group);
 
719
    }
 
720
 
 
721
  /* release the string chunk */
663
722
  if (!simple->shared_chunks)
664
 
    {
665
 
      g_mem_chunk_destroy (simple->entry_chunk);
666
 
      g_mem_chunk_destroy (simple->lentry_chunk);
667
 
      g_mem_chunk_destroy (simple->group_chunk);
668
 
      g_string_chunk_free (simple->string_chunk);
669
 
    }
 
723
    g_string_chunk_free (simple->string_chunk);
670
724
}
671
725
 
672
726
 
 
727
 
673
728
void
674
729
_xfce_rc_simple_flush (XfceRc *rc)
675
730
{
696
751
}
697
752
 
698
753
 
 
754
 
699
755
void
700
756
_xfce_rc_simple_rollback (XfceRc *rc)
701
757
{
705
761
}
706
762
 
707
763
 
 
764
 
708
765
gboolean
709
766
_xfce_rc_simple_is_dirty (const XfceRc *rc)
710
767
{
714
771
}
715
772
 
716
773
 
 
774
 
717
775
gboolean
718
776
_xfce_rc_simple_is_readonly (const XfceRc *rc)
719
777
{
723
781
}
724
782
 
725
783
 
 
784
 
726
785
const gchar*
727
786
_xfce_rc_simple_get_filename (const XfceRc *rc)
728
787
{
732
791
}
733
792
 
734
793
 
 
794
 
735
795
gchar**
736
796
_xfce_rc_simple_get_groups (const XfceRc *rc)
737
797
{
748
808
  for (group = simple->gfirst; group != NULL; group = group->next)
749
809
    {
750
810
      if (pos == size)
751
 
        {
752
 
          size *= 2;
753
 
          result = g_realloc (result, (size + 1) * sizeof (*result));
754
 
        }
 
811
  {
 
812
    size *= 2;
 
813
    result = g_realloc (result, (size + 1) * sizeof (*result));
 
814
  }
755
815
      result[pos] = g_strdup (group->name);
756
816
      ++pos;
757
817
    }
761
821
}
762
822
 
763
823
 
 
824
 
764
825
gchar**
765
 
_xfce_rc_simple_get_entries (const XfceRc *rc, const gchar *name)
 
826
_xfce_rc_simple_get_entries (const XfceRc *rc,
 
827
                             const gchar  *name)
766
828
{
767
829
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
768
830
  const Group        *group;
788
850
  for (entry = group->efirst; entry != NULL; entry = entry->next)
789
851
    {
790
852
      if (size == pos)
791
 
        {
792
 
          size *= 2;
793
 
          result = g_realloc (result, (size + 1) * sizeof (*result));
794
 
        }
 
853
        {
 
854
          size *= 2;
 
855
          result = g_realloc (result, (size + 1) * sizeof (*result));
 
856
        }
795
857
      result[pos] = g_strdup (entry->key);
796
858
      ++pos;
797
859
    }
802
864
}
803
865
 
804
866
 
 
867
 
805
868
void
806
 
_xfce_rc_simple_delete_group (XfceRc *rc, const gchar *name, gboolean global)
 
869
_xfce_rc_simple_delete_group (XfceRc      *rc,
 
870
                              const gchar *name,
 
871
                              gboolean     global)
807
872
{
808
873
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
809
874
  Group        *group;
 
875
  Entry        *entry;
 
876
  Entry        *next;
810
877
 
811
878
  if (name == NULL)
812
879
    name = NULL_GROUP;
818
885
          if (simple->group == group || strcmp (name, NULL_GROUP) == 0)
819
886
            {
820
887
              /* don't delete current group or the default group, just clear them */
 
888
              for (entry = group->efirst; entry != NULL; entry = next)
 
889
                {
 
890
                  next = entry->next;
 
891
                  simple_entry_free (entry);
 
892
                }
821
893
              group->efirst = group->elast = NULL;
822
894
            }
823
895
          else
831
903
                group->next->prev = group->prev;
832
904
              else
833
905
                simple->glast = group->prev;
 
906
 
 
907
              /* delete this group */
 
908
              simple_group_free (group);
834
909
            }
835
910
 
836
911
          simple->dirty = TRUE;
840
915
}
841
916
 
842
917
 
 
918
 
843
919
const gchar*
844
920
_xfce_rc_simple_get_group (const XfceRc *rc)
845
921
{
852
928
}
853
929
 
854
930
 
 
931
 
855
932
gboolean
856
 
_xfce_rc_simple_has_group (const XfceRc *rc, const gchar *name)
 
933
_xfce_rc_simple_has_group (const XfceRc *rc,
 
934
                           const gchar  *name)
857
935
{
858
936
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
859
937
  const Group        *group;
870
948
}
871
949
 
872
950
 
 
951
 
873
952
void
874
 
_xfce_rc_simple_set_group (XfceRc *rc, const gchar *name)
 
953
_xfce_rc_simple_set_group (XfceRc      *rc,
 
954
                           const gchar *name)
875
955
{
876
956
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
877
957
 
883
963
}
884
964
 
885
965
 
 
966
 
886
967
void
887
 
_xfce_rc_simple_delete_entry (XfceRc *rc, const gchar *key, gboolean global)
 
968
_xfce_rc_simple_delete_entry (XfceRc      *rc,
 
969
                              const gchar *key,
 
970
                              gboolean     global)
888
971
{
889
972
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
890
973
  Entry        *entry;
903
986
          else
904
987
            simple->group->elast = entry->prev;
905
988
 
 
989
          /* delete this entry */
 
990
          simple_entry_free (entry);
 
991
 
906
992
          simple->dirty = TRUE;
907
993
          break;
908
994
        }
910
996
}
911
997
 
912
998
 
 
999
 
913
1000
gboolean
914
1001
_xfce_rc_simple_has_entry (const XfceRc *rc,
915
 
                           const gchar  *key)
 
1002
                           const gchar  *key)
916
1003
{
917
1004
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
918
1005
  const Entry        *entry;
925
1012
}
926
1013
 
927
1014
 
 
1015
 
928
1016
const gchar*
929
1017
_xfce_rc_simple_read_entry (const XfceRc *rc,
930
 
                            const gchar  *key,
931
 
                            gboolean      translated)
 
1018
                            const gchar  *key,
 
1019
                            gboolean      translated)
932
1020
{
933
1021
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
934
1022
  LEntry             *lentry;
945
1033
    {
946
1034
      /* check for localized entry (best fit!) */
947
1035
      if (G_LIKELY (translated && rc->locale != NULL))
948
 
        {
949
 
          best_match = XFCE_LOCALE_NO_MATCH;
950
 
          best_value = NULL;
951
 
 
952
 
          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
953
 
            {
954
 
              match = xfce_locale_match (rc->locale, lentry->locale);
955
 
              if (match == XFCE_LOCALE_FULL_MATCH)
956
 
                {
957
 
                  /* FULL MATCH */
958
 
                  return lentry->value;
959
 
                }
960
 
              else if (match > best_match)
961
 
                {
962
 
                  best_match = match;
963
 
                  best_value = lentry->value;
964
 
                }
965
 
            }
966
 
 
967
 
          if (best_value != NULL)
968
 
            return best_value;
969
 
 
970
 
          /* FALL-THROUGH */
971
 
        }
 
1036
        {
 
1037
          best_match = XFCE_LOCALE_NO_MATCH;
 
1038
          best_value = NULL;
 
1039
 
 
1040
          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
 
1041
            {
 
1042
              match = xfce_locale_match (rc->locale, lentry->locale);
 
1043
              if (match == XFCE_LOCALE_FULL_MATCH)
 
1044
                {
 
1045
                  /* FULL MATCH */
 
1046
                  return lentry->value;
 
1047
                }
 
1048
              else if (match > best_match)
 
1049
                {
 
1050
                  best_match = match;
 
1051
                  best_value = lentry->value;
 
1052
                }
 
1053
            }
 
1054
 
 
1055
          if (best_value != NULL)
 
1056
            return best_value;
 
1057
 
 
1058
          /* FALL-THROUGH */
 
1059
        }
972
1060
 
973
1061
      return entry->value;
974
1062
    }
977
1065
}
978
1066
 
979
1067
 
 
1068
 
980
1069
void
981
1070
_xfce_rc_simple_write_entry (XfceRc      *rc,
982
 
                             const gchar *key,
983
 
                             const gchar *value)
 
1071
                             const gchar *key,
 
1072
                             const gchar *value)
984
1073
{
985
1074
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
986
1075
  Entry        *result;
990
1079
    simple->dirty = TRUE;
991
1080
}
992
1081
 
 
1082
 
 
1083
 
 
1084
#define __XFCE_RC_SIMPLE_C__
 
1085
#include <libxfce4util/libxfce4util-aliasdef.c>