Fix move command parsing.
[fvwm.git] / modules / FvwmGtk / expand.c
blob30276f2043e6a725939f2c464de60843f39e4e5f
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "config.h"
19 #include <gtk/gtk.h>
21 #include "libs/fvwmlib.h"
24 typedef struct str_struct
26 struct str_struct *next;
27 char *s;
28 int is_var;
29 } str;
31 /* split string val into a list of str's, each containing
32 an ordinary substring or a variable reference of the form $(bla).
33 The list is appended to pre, the last list entry is returned.
35 static str *
36 split_string (char *val, str *pre)
38 char *s = NULL, *t = NULL;
39 char *v = val;
40 str *curr = pre;
42 while (v && *v)
44 s = strstr (v, "$(");
45 if (s)
47 t = strstr (s, ")");
50 if (s && t)
52 /* append the part before $( */
53 curr->next = (str *) safemalloc (sizeof (str));
54 curr = curr->next;
55 *s = '\0';
56 curr->s = safestrdup (v);
57 curr->is_var = 0;
58 *s = '$';
60 /* append the variable reference, silently omit the ) */
61 curr->next = (str *) safemalloc (sizeof (str));
62 curr = curr->next;
63 curr->next = NULL;
64 *t = '\0';
65 curr->s = safestrdup (s + 2);
66 curr->is_var = 1;
67 *t = ')';
69 v = t + 1;
71 else
73 /* append the part after the last variable reference */
74 curr->next = (str *) safemalloc (sizeof (str));
75 curr = curr->next;
76 curr->next = NULL;
77 curr->s = safestrdup (v);
78 curr->is_var = 0;
79 v = NULL;
82 return curr;
86 static char *
87 combine_string (str *p)
89 str *r, *next;
90 int l;
91 char *res;
93 for (l = 1, r = p; r != NULL; r = r->next)
95 l += strlen (r->s);
97 res = (char *) safemalloc (l * sizeof (char));
98 *res = '\0';
99 for (r = p; r != NULL; r = next)
101 strcat (res, r->s);
102 next = r->next;
103 free (r->s);
104 free (r);
106 return res;
110 char *
111 recursive_replace (GtkWidget *d, char *val)
113 str *head, *r, *tail, *next;
114 char *nval;
116 head = (str *) safemalloc (sizeof (str));
117 head->is_var = 0;
118 head->s = safestrdup("");
119 head->next = NULL;
121 split_string (val, head);
122 for (r = head; r->next != NULL; r = r->next)
124 next = r->next;
125 if (next->is_var)
127 nval = (char *) gtk_object_get_data (GTK_OBJECT (d), next->s);
128 if (nval)
130 /* this changes r->next, thus freeing next is safe */
131 tail = split_string (nval, r);
132 tail->next = next->next;
133 free (next->s);
134 free (next);
136 else
138 next->is_var = 0;
142 return combine_string (head);