1 /* -*-c-*- */
2 /*
3 * ParseComand.c was originally part of FvwmForm.c.
4 *
5 * Turned into separate file 02/27/99, Dan Espen.
6 *
7 * FvwmForm is original work of Thomas Zuwei Feng.
8 *
9 * Copyright Feb 1995, Thomas Zuwei Feng. No guarantees or warantees are
10 * provided or implied in any way whatsoever. Use this program at your own
11 * risk. Permission to use, modify, and redistribute this program is hereby
12 * given, provided that this copyright is kept intact.
13 */
14
15 /* This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see: <http://www.gnu.org/licenses/>
27 */
28
29 #include "config.h"
30 #include "libs/fvwmlib.h"
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <FvwmForm.h> /* common FvwmForm stuff */
35
36 static char *buf;
37 static int N = 8;
38
39 /* Macro used in following functions */
40 #define AddChar(chr) \
41 { if (dn >= N) {\
42 N *= 2;\
43 buf = fxrealloc(buf, N, sizeof(buf));\
44 }\
45 buf[dn++] = (chr);\
46 }
47
48 /* do var substitution for command string */
ParseCommand(int dn,char * sp,char end,int * dn1,char ** sp1)49 char * ParseCommand (int dn, char *sp, char end, int *dn1, char **sp1)
50 {
51 static char var[256];
52 char c, x, *cp, *vp;
53 int j, dn2;
54 int added_sel;
55 Item *item;
56
57 if (buf == 0) { /* if no buffer yet */
58 buf = (char *)malloc(N);
59 }
60 while (1) {
61 c = *(sp++);
62 if (c == '\0' || c == end) { /* end of substitution */
63 *dn1 = dn;
64 *sp1 = sp;
65 if (end == 0) { /* if end of command reached */
66 AddChar('\0'); /* make sure theres a null */
67 }
68 return(buf);
69 }
70 if (c == '$') { /* variable */
71 if (*sp != '(')
72 goto normal_char;
73 ++sp;
74 vp = var;
75 while (1) {
76 x = *(sp++);
77 if (x == '\\') {
78 *(vp++) = '\\';
79 *(vp++) = *(sp++);
80 }
81 else if (x == ')' || x == '?' || x == '!') {
82 *(vp++) = '\0';
83 break;
84 }
85 else if (!isspace(x))
86 *(vp++) = x;
87 }
88 for (item = root_item_ptr; item != 0;
89 item = item->header.next) {/* all items */
90 if (strcmp(var, item->header.name) == 0) {
91 switch (item->type) {
92 case I_INPUT:
93 if (x == ')') {
94 for (cp = item->input.value; *cp != '\0'; cp++) {
95 AddChar(*cp);
96 }
97 } else {
98 ParseCommand(dn, sp, ')', &dn2, &sp);
99 if ((x == '?' && strlen(item->input.value) > 0) ||
100 (x == '!' && strlen(item->input.value) == 0))
101 dn = dn2;
102 }
103 break;
104 case I_CHOICE:
105 if (x == ')') {
106 for (cp = item->choice.value; *cp != '\0'; cp++)
107 AddChar(*cp);
108 } else {
109 ParseCommand(dn, sp, ')', &dn2, &sp);
110 if ((x == '?' && item->choice.on) ||
111 (x == '!' && !item->choice.on))
112 dn = dn2;
113 }
114 break;
115 case I_SELECT:
116 if (x != ')')
117 ParseCommand(dn, sp, ')', &dn2, &sp);
118 added_sel=0;
119 for (j = 0; j < item->selection.n; j++) {
120 if (item->selection.choices[j]->choice.on) {
121 if (added_sel) { /* if not first sel added */
122 AddChar(' '); /* insert space before next value */
123 }
124 added_sel=1;
125 for (cp = item->selection.choices[j]->choice.value;
126 *cp != '\0'; cp++) {
127 AddChar(*cp);
128 }
129 }
130 }
131 break;
132 }
133 goto next_loop;
134 }
135 }
136 goto next_loop;
137 } /* end char is $, not followed by ( */
138 /* if char is \, followed by ), want to pass thru the paren literally */
139 if (c == '\\' && *sp == ')') {
140 c = *(sp++); /* skip to the paren */
141 }
142 normal_char:
143 AddChar(c);
144 next_loop:
145 ;
146 }
147 }
148