summaryrefslogtreecommitdiffabout
path: root/gconf/gconf-gram.y
Unidiff
Diffstat (limited to 'gconf/gconf-gram.y') (more/less context) (ignore whitespace changes)
-rw-r--r--gconf/gconf-gram.y891
1 files changed, 0 insertions, 891 deletions
diff --git a/gconf/gconf-gram.y b/gconf/gconf-gram.y
deleted file mode 100644
index c2d833b..0000000
--- a/gconf/gconf-gram.y
+++ b/dev/null
@@ -1,891 +0,0 @@
1%{
2/* gconf - General purpose configuration parser.
3 Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3 of the License, or (at your
8 option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21#include <gconf.h>
22#include <gconf-gram.h>
23#include <stdlib.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <sys/time.h>
27#include <sys/un.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <netdb.h>
31
32#include <xalloc.h>
33#include <inttypes.h>
34
35#if ENABLE_NLS
36# include "gettext.h"
37# define _(msgid) gettext (msgid)
38#else
39# define _(msgid) msgid
40#endif
41
42typedef union
43{
44 struct sockaddr s;
45 struct sockaddr_in s_in;
46 struct sockaddr_un s_un;
47} sockaddr_union_t;
48
49static struct gconf_keyword config_keywords;
50static struct gconf_keyword *cursect;
51static gl_list_t sections;
52int gconf_error_count;
53
54int gconf_default_port = 0;
55
56static void *target_ptr(struct gconf_keyword *kwp);
57static void stmt_begin(struct gconf_keyword *kwp, gconf_value_t tag);
58static void stmt_end(struct gconf_keyword *kwp);
59static struct gconf_keyword *find_keyword(const char *ident);
60
61static void process_ident(struct gconf_keyword *kwp, gconf_value_t *value);
62static gl_list_t simple_list_create (bool dispose);
63%}
64
65%union {
66 char *string;
67 gconf_value_t value;
68 gl_list_t list;
69 struct gconf_keyword *kw;
70}
71
72%token <string> IDENT STRING QSTRING MSTRING
73%type <string> string slist
74%type <list> slist0
75%type <value> value tag vallist
76%type <list> values list vlist
77%type <kw> ident
78
79%%
80
81input : stmtlist
82 ;
83
84stmtlist: stmt
85 | stmtlist stmt
86 ;
87
88stmt : simple
89 | block
90 ;
91
92simple : ident vallist ';'
93 {
94 process_ident($1, &$2);
95 }
96 ;
97
98block : ident tag { stmt_begin($<kw>1, $<value>2); } '{' stmtlist '}' opt_sc
99 {
100 stmt_end($1);
101 }
102 ;
103
104ident : IDENT
105 {
106 $$ = find_keyword($1);
107 if (!$$)
108 gconf_error(&gconf_current_locus, 0, _("Unknown keyword"));
109 }
110 ;
111
112tag : /* empty */
113 {
114 $$.type = GCONF_TYPE_STRING;
115 $$.v.string = NULL;
116 }
117 | value
118 ;
119
120vallist : vlist
121 {
122 size_t n;
123
124 if ((n = gl_list_size ($1)) == 1)
125 {
126 $$ = *(gconf_value_t *)gl_list_get_at ($1, 0);
127 }
128 else
129 {
130 size_t i;
131
132 $$.type = GCONF_TYPE_ARRAY;
133 $$.v.arg.c = n;
134 $$.v.arg.v = xcalloc (n, sizeof ($$.v.arg.v[0]));
135 for (i = 0; i < n; i++)
136 $$.v.arg.v[i] = *(gconf_value_t *)gl_list_get_at ($1, i);
137 }
138 gl_list_free ($1);
139 }
140 ;
141
142vlist : value
143 {
144 $$ = simple_list_create (false);
145 gl_list_add_last ($$, gconf_value_dup (&$1));
146 }
147 | vlist value
148 {
149 gl_list_add_last ($1, gconf_value_dup (&$2));
150 }
151 ;
152
153value : string
154 {
155 $$.type = GCONF_TYPE_STRING;
156 $$.v.string = $1;
157 }
158 | list
159 {
160 $$.type = GCONF_TYPE_LIST;
161 $$.v.list = $1;
162 }
163 | MSTRING
164 {
165 $$.type = GCONF_TYPE_STRING;
166 $$.v.string = $1;
167 }
168 ;
169
170string : STRING
171 | IDENT
172 | slist
173 ;
174
175slist : slist0
176 {
177 const void *p;
178 gl_list_iterator_t itr = gl_list_iterator ($1);
179
180 gconf_line_begin ();
181 while (gl_list_iterator_next (&itr, &p, NULL))
182 gconf_line_add (p, strlen (p));
183 $$ = gconf_line_finish ();
184 gl_list_iterator_free (&itr);
185 gl_list_free ($1);
186 }
187 ;
188
189slist0 : QSTRING
190 {
191 $$ = simple_list_create (false);
192 gl_list_add_last ($$, $1);
193 }
194 | slist0 QSTRING
195 {
196 gl_list_add_last ($1, $2);
197 $$ = $1;
198 }
199 ;
200
201list : '(' ')'
202 {
203 $$ = NULL;
204 }
205 | '(' values ')'
206 {
207 $$ = $2;
208 }
209 | '(' values ',' ')'
210 {
211 $$ = $2;
212 }
213 ;
214
215values : value
216 {
217 $$ = simple_list_create (true);
218 gl_list_add_last ($$, gconf_value_dup (&$1));
219 }
220 | values ',' value
221 {
222 gl_list_add_last ($1, gconf_value_dup (&$3));
223 $$ = $1;
224 }
225 ;
226
227opt_sc : /* empty */
228 | ';'
229 ;
230
231%%
232
233int
234yyerror(char *s)
235{
236 gconf_error (&gconf_current_locus, 0, "%s", s);
237 return 0;
238}
239
240static void
241listel_dispose(const void *el)
242{
243 free((void*)el);
244}
245
246static gl_list_t
247simple_list_create (bool dispose)
248{
249 return gl_list_create_empty(&gl_linked_list_implementation,
250 NULL,
251 NULL,
252 dispose ? listel_dispose : NULL,
253 false);
254}
255
256
257void
258gconf_warning(gconf_locus_t *locus, int errcode, const char *fmt, ...)
259{
260 va_list ap;
261 char *buf = NULL;
262
263 va_start (ap, fmt);
264 vasprintf (&buf, fmt, ap);
265 va_end (ap);
266 gconf_print_diag (locus, 0, errcode, buf);
267 free(buf);
268}
269
270void
271gconf_error (gconf_locus_t *locus, int errcode, const char *fmt, ...)
272{
273 va_list ap;
274 char *buf = NULL;
275
276 va_start (ap, fmt);
277 vasprintf (&buf, fmt, ap);
278 va_end (ap);
279 gconf_print_diag (locus, 1, errcode, buf);
280 free (buf);
281 gconf_error_count++;
282}
283
284void
285gconf_set_keywords (struct gconf_keyword *kwd)
286{
287 config_keywords.kwd = kwd;
288}
289
290int
291gconf_parse (const char *name)
292{
293 int rc;
294 if (gconf_lex_begin (name))
295 return 1;
296 cursect = &config_keywords;
297 if (sections)
298 {
299 gl_list_free (sections);
300 sections = NULL;
301 }
302 rc = yyparse ();
303 gconf_lex_end ();
304 if (gconf_error_count)
305 rc = 1;
306 return rc;
307}
308
309void
310gconf_gram_trace (int n)
311{
312 yydebug = n;
313}
314
315
316
317static void *
318target_ptr (struct gconf_keyword *kwp)
319{
320 char *base;
321
322 if (kwp->varptr)
323 base = (char*) kwp->varptr + kwp->offset;
324 else if (cursect && cursect->callback_data)
325 base = (char*) cursect->callback_data + kwp->offset;
326 else
327 base = NULL;
328 return base;
329}
330
331static int
332fake_callback (enum gconf_callback_command cmd,
333 gconf_locus_t *locus,
334 void *varptr,
335 gconf_value_t *value,
336 void *cb_data)
337{
338 return 0;
339}
340
341static struct gconf_keyword fake = {
342 "*",
343 NULL,
344 NULL,
345 gconf_type_void,
346 NULL,
347 0,
348 fake_callback,
349 NULL,
350 &fake
351};
352
353static void
354stmt_begin (struct gconf_keyword *kwp, gconf_value_t tag)
355{
356 void *target;
357
358 if (!sections)
359 sections = simple_list_create (false);
360 gl_list_add_first (sections, cursect);
361 if (kwp)
362 {
363 target = target_ptr (kwp);
364 cursect = kwp;
365 if (kwp->callback && kwp->callback (gconf_callback_section_begin,
366 &gconf_current_locus, /* FIXME */
367 target,
368 &tag,
369 &kwp->callback_data))
370 cursect = &fake;
371 }
372 else
373 /* install "ignore-all" section */
374 cursect = kwp;
375}
376
377static void
378stmt_end (struct gconf_keyword *kwp)
379{
380 gconf_callback_fn callback = NULL;
381 void *dataptr = NULL;
382
383 if (cursect && cursect->callback)
384 {
385 callback = cursect->callback;
386 dataptr = &cursect->callback_data;
387 }
388
389 if (gl_list_size (sections) == 0)
390 abort ();
391 cursect = (struct gconf_keyword *) gl_list_get_at (sections, 0);
392 gl_list_remove_at (sections, 0);
393 if (callback)
394 callback (gconf_callback_section_end,
395 &gconf_current_locus, /* FIXME */
396 kwp ? target_ptr(kwp) : NULL,
397 NULL,
398 dataptr);
399
400}
401
402static struct gconf_keyword *
403find_keyword (const char *ident)
404{
405 struct gconf_keyword *kwp;
406
407 if (cursect && cursect != &fake)
408 {
409 for (kwp = cursect->kwd; kwp->ident; kwp++)
410 if (strcmp (kwp->ident, ident) == 0)
411 return kwp;
412 }
413 else
414 {
415 return &fake;
416 }
417 return NULL;
418}
419
420static int
421string_to_signed (intmax_t *sval, const char *string,
422 intmax_t minval, intmax_t maxval)
423{
424 intmax_t t;
425 char *p;
426
427 t = strtoimax (string, &p, 0);
428 if (*p)
429 {
430 gconf_error (&gconf_current_locus, 0, _("cannot convert `%s' to number"),
431 string);
432 return 1;
433 }
434 else if (t < minval || t > maxval)
435 {
436 gconf_error (&gconf_current_locus, 0,
437 _("%s: value out of allowed range %"PRIiMAX"..%"PRIiMAX),
438 string, minval, maxval);
439 return 1;
440 }
441 *sval = t;
442 return 0;
443}
444
445static int
446string_to_unsigned (uintmax_t *sval, const char *string, uintmax_t maxval,
447 gconf_locus_t *loc)
448{
449 uintmax_t t;
450 char *p;
451
452 t = strtoumax (string, &p, 0);
453 if (*p)
454 {
455 gconf_error (loc, 0, _("cannot convert `%s' to number"),
456 string);
457 return 1;
458 }
459 else if (t > maxval)
460 {
461 gconf_error (loc, 0,
462 _("%s: value out of allowed range 0..%"PRIuMAX),
463 string, maxval);
464 return 1;
465 }
466 *sval = t;
467 return 0;
468}
469
470static int
471string_to_bool (const char *string, int *pval)
472{
473 if (strcmp (string, "yes") == 0
474 || strcmp (string, "true") == 0
475 || strcmp (string, "t") == 0
476 || strcmp (string, "1") == 0)
477 *pval = 1;
478 else if (strcmp (string, "no") == 0
479 || strcmp (string, "false") == 0
480 || strcmp (string, "nil") == 0
481 || strcmp (string, "0") == 0)
482 *pval = 0;
483 else
484 {
485 gconf_error (&gconf_current_locus, 0,
486 _("%s: not a valid boolean value"),
487 string);
488 return 1;
489 }
490 return 0;
491}
492
493static int
494string_to_host (struct in_addr *in, const char *string)
495{
496 if (inet_aton (string, in) == 0)
497 {
498 struct hostent *hp;
499
500 hp = gethostbyname (string);
501 if (hp == NULL)
502 return 1;
503 memcpy (in, hp->h_addr, sizeof (struct in_addr));
504 }
505 return 0;
506}
507
508static int
509string_to_sockaddr (struct gconf_sockaddr *sp, const char *string)
510{
511 if (string[0] == '/')
512 {
513 struct sockaddr_un s_un;
514 if (strlen (string) >= sizeof (s_un.sun_path))
515 {
516 gconf_error (&gconf_current_locus, 0,
517 _("%s: UNIX socket name too long"),
518 string);
519 return 1;
520 }
521 s_un.sun_family = AF_UNIX;
522 strcpy (s_un.sun_path, string);
523 sp->len = sizeof (s_un);
524 sp->sa = xmalloc (sp->len);
525 memcpy (sp->sa, &s_un, sp->len);
526 }
527 else
528 {
529 char *p = strchr (string, ':');
530 size_t len;
531 struct sockaddr_in sa;
532
533 sa.sin_family = AF_INET;
534 if (p)
535 len = p - string;
536 else
537 len = strlen (string);
538
539 if (len == 0)
540 sa.sin_addr.s_addr = INADDR_ANY;
541 else
542 {
543 char *host = xmalloc (len + 1);
544 memcpy (host, string, len);
545 host[len] = 0;
546
547 if (string_to_host (&sa.sin_addr, host))
548 {
549 gconf_error (&gconf_current_locus, 0,
550 _("%s: not a valid IP address or hostname"),
551 host);
552 free (host);
553 return 1;
554 }
555 free (host);
556 }
557
558 if (p)
559 {
560 struct servent *serv;
561
562 p++;
563 serv = getservbyname (p, "tcp");
564 if (serv != NULL)
565 sa.sin_port = serv->s_port;
566 else
567 {
568 unsigned long l;
569 char *q;
570
571 /* Not in services, maybe a number? */
572 l = strtoul (p, &q, 0);
573
574 if (*q || l > USHRT_MAX)
575 {
576 gconf_error (&gconf_current_locus, 0,
577 _("%s: not a valid port number"), p);
578 return 1;
579 }
580 sa.sin_port = htons (l);
581 }
582 }
583 else if (gconf_default_port)
584 sa.sin_port = gconf_default_port;
585 else
586 {
587 gconf_error (&gconf_current_locus, 0, _("missing port number"));
588 return 1;
589 }
590 sp->len = sizeof (sa);
591 sp->sa = xmalloc (sp->len);
592 memcpy (sp->sa, &sa, sp->len);
593 }
594 return 0;
595}
596
597int
598gconf_string_convert (void *target, enum gconf_data_type type,
599 const char *string)
600{
601 uintmax_t uval;
602 intmax_t sval;
603
604 switch (type)
605 {
606 case gconf_type_void:
607 abort ();
608
609 case gconf_type_string:
610 *(const char**)target = string;
611 break;
612
613 case gconf_type_short:
614 if (string_to_signed (&sval, string, SHRT_MIN, SHRT_MAX) == 0)
615 *(short*)target = sval;
616 else
617 return 1;
618 break;
619
620 case gconf_type_ushort:
621 if (string_to_unsigned (&uval, string, USHRT_MAX, &gconf_current_locus) == 0)
622 *(unsigned short*)target = uval;
623 else
624 return 1;
625 break;
626
627 case gconf_type_bool:
628 return string_to_bool (string, (int*)target);
629
630 case gconf_type_int:
631 if (string_to_signed (&sval, string, INT_MIN, INT_MAX) == 0)
632 *(int*)target = sval;
633 else
634 return 1;
635 break;
636
637 case gconf_type_uint:
638 if (string_to_unsigned (&uval, string, UINT_MAX, &gconf_current_locus) == 0)
639 *(unsigned int*)target = uval;
640 else
641 return 1;
642 break;
643
644 case gconf_type_long:
645 if (string_to_signed (&sval, string, LONG_MIN, LONG_MAX) == 0)
646 *(long*)target = sval;
647 else
648 return 1;
649 break;
650
651 case gconf_type_ulong:
652 if (string_to_unsigned (&uval, string, ULONG_MAX, &gconf_current_locus) == 0)
653 *(unsigned long*)target = uval;
654 else
655 return 1;
656 break;
657
658 case gconf_type_size:
659 if (string_to_unsigned (&uval, string, SIZE_MAX, &gconf_current_locus) == 0)
660 *(size_t*)target = uval;
661 else
662 return 1;
663 break;
664
665 case gconf_type_intmax:
666 return string_to_signed ((intmax_t*)target, string,
667 INTMAX_MIN, INTMAX_MAX);
668
669 case gconf_type_uintmax:
670 return string_to_unsigned ((uintmax_t*)target, string, UINTMAX_MAX,
671 &gconf_current_locus);
672
673 case gconf_type_time:
674 /*FIXME: Use getdate */
675 if (string_to_unsigned (&uval, string, (time_t)-1, &gconf_current_locus) == 0)
676 *(time_t*)target = uval;
677 else
678 return 1;
679 break;
680
681 case gconf_type_ipv4:
682 if (inet_aton (string, (struct in_addr *)target))
683 {
684 gconf_error (&gconf_current_locus, 0, _("%s: not a valid IP address"), string);
685 return 1;
686 }
687 break;
688
689 case gconf_type_host:
690 if (string_to_host ((struct in_addr *)target, string))
691 {
692 gconf_error (&gconf_current_locus, 0,
693 _("%s: not a valid IP address or hostname"), string);
694 return 1;
695 }
696 break;
697
698 case gconf_type_sockaddr:
699 return string_to_sockaddr ((struct gconf_sockaddr *)target, string);
700
701 /* FIXME: */
702 case gconf_type_cidr:
703 gconf_error (&gconf_current_locus, 0, _("INTERNAL ERROR at %s:%d"), __FILE__,
704 __LINE__);
705 abort();
706
707 case gconf_type_section:
708 gconf_error (&gconf_current_locus, 0,
709 _("Invalid use of block statement"));
710 return 1;
711 }
712 return 0;
713}
714
715struct gconf_prop
716{
717 size_t size;
718 gl_listelement_equals_fn eqfn;
719};
720
721static bool
722string_eq (const void *elt1, const void *elt2)
723{
724 return strcmp ((const char *)elt1, (const char *)elt2) == 0;
725}
726
727#define __gconf_name_cat__(a,b) a ## b
728#define NUMEQ(type) __gconf_name_cat__(type,_eq)
729 #define __DECL_NUMEQ(type,ctype) \
730 static bool \
731 NUMEQ(type) (const void *elt1, const void *elt2)\
732 { \
733 return memcmp (elt1, elt2, sizeof (ctype)) == 0;\
734 }
735#define DECL_NUMEQ(type) __DECL_NUMEQ(type,type)
736
737DECL_NUMEQ(short)
738DECL_NUMEQ(int)
739DECL_NUMEQ(long)
740DECL_NUMEQ(size_t)
741DECL_NUMEQ(uintmax_t)
742DECL_NUMEQ(intmax_t)
743DECL_NUMEQ(time_t)
744__DECL_NUMEQ(in_addr, struct in_addr)
745__DECL_NUMEQ(gconf_sockaddr, struct gconf_sockaddr)
746
747struct gconf_prop gconf_prop_tab[] = {
748 { 0, NULL }, /* gconf_type_void */
749 { sizeof (char*), string_eq }, /* gconf_type_string */
750 { sizeof (short), NUMEQ (short) }, /* gconf_type_short */
751 { sizeof (unsigned short), NUMEQ (short) }, /* gconf_type_ushort */
752 { sizeof (int), NUMEQ (int) }, /* gconf_type_int */
753 { sizeof (unsigned int), NUMEQ (int) }, /* gconf_type_uint */
754 { sizeof (long), NUMEQ (long) }, /* gconf_type_long */
755 { sizeof (unsigned long), NUMEQ (long) }, /* gconf_type_ulong */
756 { sizeof (size_t), NUMEQ (size_t) }, /* gconf_type_size */
757 /* gconf_type_off,*/
758 { sizeof (uintmax_t), NUMEQ (uintmax_t) }, /* gconf_type_uintmax */
759 { sizeof (intmax_t), NUMEQ (intmax_t) }, /* gconf_type_intmax */
760 { sizeof (time_t), NUMEQ (time_t) }, /* gconf_type_time */
761 { sizeof (int), NUMEQ (int) }, /* gconf_type_bool */
762 { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_ipv4 */
763 { 0, NULL }, /* FIXME: gconf_type_cidr */
764 { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_host */
765 { sizeof (struct gconf_sockaddr), NUMEQ (gconf_sockaddr) },
766 /* gconf_type_sockaddr */
767 { 0, NULL } /* gconf_type_section */
768};
769#define gconf_prop_count \
770 (sizeof (gconf_prop_tab) / sizeof (gconf_prop_tab[0]))
771
772static void
773process_ident (struct gconf_keyword *kwp, gconf_value_t *value)
774{
775 void *target;
776
777 if (!kwp)
778 return;
779
780 target = target_ptr (kwp);
781
782 if (kwp->callback)
783 kwp->callback (gconf_callback_set_value,
784 &gconf_current_locus, /* FIXME */
785 target,
786 value,
787 &kwp->callback_data);
788 else if (value->type == GCONF_TYPE_ARRAY)
789 {
790 gconf_error (&gconf_current_locus, 0,
791 _("too many arguments to `%s'; missing semicolon?"),
792 kwp->ident);
793 return;
794 }
795 else if (value->type == GCONF_TYPE_LIST)
796 {
797 if (GCONF_IS_LIST (kwp->type))
798 {
799 gl_list_iterator_t itr = gl_list_iterator (value->v.list);
800 enum gconf_data_type type = GCONF_TYPE (kwp->type);
801 int num = 1;
802 const void *p;
803 gl_list_t list;
804 size_t size;
805
806 if (type >= gconf_prop_count
807 || (size = gconf_prop_tab[type].size) == 0)
808 {
809 gconf_error (&gconf_current_locus, 0,
810 _("INTERNAL ERROR at %s:%d: "
811 "unhandled data type %d"),
812 __FILE__, __LINE__, type);
813 abort ();
814 }
815
816 list = gl_list_create_empty (&gl_linked_list_implementation,
817 gconf_prop_tab[type].eqfn,
818 NULL,
819 listel_dispose,
820 false);
821
822 while (gl_list_iterator_next (&itr, &p, NULL))
823 {
824 const gconf_value_t *vp = p;
825
826 if (vp->type != GCONF_TYPE_STRING)
827 gconf_error (&gconf_current_locus, 0,
828 _("%s: incompatible data type in list item #%d"),
829 kwp->ident, num);
830 else if (type == gconf_type_string)
831 gl_list_add_last (list, vp->v.string);
832 else
833 {
834 void *ptr = xmalloc (size);
835 if (gconf_string_convert (ptr, type, vp->v.string) == 0)
836 gl_list_add_last (list, ptr);
837 else
838 free (ptr);
839 }
840 }
841 gl_list_iterator_free (&itr);
842 *(gl_list_t*)target = list;
843 }
844 else
845 {
846 gconf_error (&gconf_current_locus, 0,
847 _("incompatible data type for `%s'"),
848 kwp->ident);
849 return;
850 }
851 }
852 else if (GCONF_IS_LIST (kwp->type))
853 {
854 gl_list_t list;
855 enum gconf_data_type type = GCONF_TYPE (kwp->type);
856 size_t size;
857 void *ptr;
858
859 if (type >= gconf_prop_count
860 || (size = gconf_prop_tab[type].size) == 0)
861 {
862 gconf_error (&gconf_current_locus, 0,
863 _("INTERNAL ERROR at %s:%d: unhandled data type %d"),
864 __FILE__, __LINE__, type);
865 abort();
866 }
867
868 list = gl_list_create_empty (&gl_linked_list_implementation,
869 gconf_prop_tab[type].eqfn,
870 NULL,
871 listel_dispose,
872 false);
873 if (type == gconf_type_string)
874 gl_list_add_last (list, value->v.string);
875 else
876 {
877 ptr = xmalloc (size);
878 if (gconf_string_convert (ptr, type, value->v.string))
879 {
880 free (ptr);
881 gl_list_free (list);
882 return;
883 }
884 gl_list_add_last (list, ptr);
885 }
886 *(gl_list_t*)target = list;
887 }
888 else
889 gconf_string_convert (target, GCONF_TYPE (kwp->type), value->v.string);
890}
891

Return to:

Send suggestions and report system problems to the System administrator.