1 kumpf 1.2 /*
2 //%2006////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
5 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
6 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
7 // IBM Corp.; EMC Corporation, The Open Group.
8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
9 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
10 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
11 // EMC Corporation; VERITAS Software Corporation; The Open Group.
12 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
13 // EMC Corporation; Symantec Corporation; The Open Group.
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a copy
16 // of this software and associated documentation files (the "Software"), to
17 // deal in the Software without restriction, including without limitation the
18 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
19 // sell copies of the Software, and to permit persons to whom the Software is
20 // furnished to do so, subject to the following conditions:
21 //
22 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
24 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 //%/////////////////////////////////////////////////////////////////////////////
32 */
33
34 #include <string.h>
35 #include "Defines.h"
36 #include "Macro.h"
37 #include "Strlcpy.h"
38 #include "Strlcat.h"
39 #include "Log.h"
40 #include "Config.h"
41 #include "Globals.h"
42 #include "Path.h"
43 kumpf 1.2 #include <assert.h>
44
45 /*
46 **==============================================================================
47 **
48 ** Macro
49 **
50 ** This structure defines a macro (a name-value pair).
51 **
52 **==============================================================================
53 */
54
55 struct Macro
56 {
57 char* name;
58 char* value;
59 struct Macro* next;
60 };
61
62 /*
63 **==============================================================================
64 kumpf 1.2 **
65 ** _macros
66 **
67 ** The list of process macros.
68 **
69 **==============================================================================
70 */
71
72 static struct Macro* _macros = 0;
73
74 /*
75 **==============================================================================
76 **
77 ** FindMacro()
78 **
79 ** Find the value of the named macro. Return pointer to value or NULL if
80 ** not found.
81 **
82 **==============================================================================
83 */
84
85 kumpf 1.2 const char* FindMacro(const char* name)
86 {
87 const struct Macro* p;
88
89 for (p = _macros; p; p = p->next)
90 {
91 if (strcmp(p->name, name) == 0)
92 return p->value;
93 }
94
95 /* Not found. */
96 return NULL;
97 }
98
99 /*
100 **==============================================================================
101 **
102 ** DefineMacro()
103 **
104 ** Add a new macro to the macro list.
105 **
106 kumpf 1.2 **==============================================================================
107 */
108
109 int DefineMacro(const char* name, const char* value)
110 {
111 struct Macro* macro;
112
113 /* Reject if the macro is already defined. */
114
115 if (FindMacro(name) != NULL)
116 return -1;
117
118 /* Create new macro. */
119
120 macro = (struct Macro*)malloc(sizeof(struct Macro));
121 macro->name = strdup(name);
122 macro->value = strdup(value);
123
124 /* Add to end of list. */
125
126 {
127 kumpf 1.2 struct Macro* p;
128 struct Macro* prev = NULL;
129
130 for (p = _macros; p; p = p->next)
131 prev = p;
132
133 if (prev)
134 prev->next = macro;
135 else
136 _macros = macro;
137
138 macro->next = NULL;
139 }
140
141 return 0;
142 }
143
144 /*
145 **==============================================================================
146 **
147 ** UndefineMacro()
148 kumpf 1.2 **
149 ** Remove the given macro from the macro table.
150 **
151 **==============================================================================
152 */
153
154 int UndefineMacro(const char* name)
155 {
156 struct Macro* p;
157 struct Macro* prev;
158
159 for (p = _macros, prev = 0; p; p = p->next)
160 {
161 if (strcmp(p->name, name) == 0)
162 {
163 if (prev)
164 prev->next = p->next;
165 else
166 _macros = p->next;
167
168 free(p->name);
169 kumpf 1.2 free(p->value);
170 free(p);
171 return 0;
172 }
173
174 prev = p;
175 }
176
177 /* Not found. */
178 return -1;
179 }
180
181 /*
182 **==============================================================================
183 **
184 ** ExpandMacros()
185 **
186 ** Expand all macros in *input*. Leave result in *output*.
187 **
188 **==============================================================================
189 */
190 kumpf 1.2
191 int ExpandMacros(const char* input, char output[EXECUTOR_BUFFER_SIZE])
192 {
193 char buffer[EXECUTOR_BUFFER_SIZE];
194 char* p;
195
196 /* Make copy of input since we'll need to destroy it. */
197
198 Strlcpy(buffer, input, sizeof(buffer));
199 output[0] = '\0';
200
201 /* Traverse buffer, copying characters and expanding macros as we go. */
202
203 for (p = buffer; *p; )
204 {
205 /* Look for start of macro. */
206
207 if (p[0] == '$' && p[1] == '{')
208 {
209 char* q;
210
211 kumpf 1.2 /* Set p and q as follows.
212 *
213 * p q
214 * | |
215 * v v
216 * "...${MY_MACRO}..."
217 */
218
219 p += 2;
220
221 /* Find end of macro. */
222
223 for (q = p; *q && *q != '}'; q++)
224 ;
225
226 if (*q != '}')
227 {
228 Log(LL_SEVERE, "ExpandMacros(): corrupt input: %s", input);
229 return -1;
230 }
231
232 kumpf 1.2 /* Replace '}' with null-terminator. */
233
234 *q = '\0';
235
236 /* Lookup macro and append value. */
237
238 {
239 const char* value;
240 value = FindMacro(p);
241
242 if (!value)
243 {
244 Log(LL_SEVERE, "ExpandMacros(): Undefined macro: %s", p);
245 return -1;
246 }
247
248 Strlcat(output, value, EXECUTOR_BUFFER_SIZE);
249 }
250
251 p = q + 1;
252 }
253 kumpf 1.2 else
254 {
255 /* Append current character to output. */
256
257 char two[2];
258 two[0] = *p++;
259 two[1] = '\0';
260
261 Strlcat(output, two, EXECUTOR_BUFFER_SIZE);
262 }
263 }
264
265 return 0;
266 }
267
268 /*
269 **==============================================================================
270 **
271 ** DefineConfigPathMacro()
272 **
273 ** Define a new path macro whose value is taken from the given
274 kumpf 1.2 ** configuration parameter. If no such configuration parameter is defined,
275 ** use the defaultPath.
276 **
277 **==============================================================================
278 */
279
280 int DefineConfigPathMacro(const char* configParam, const char* defaultPath)
281 {
282 char path[EXECUTOR_BUFFER_SIZE];
283 int status;
284
285 status = 0;
286
287 do
288 {
289 char buffer[EXECUTOR_BUFFER_SIZE];
290
291 /* First try to get value from configuration. */
292
293 if (GetConfigParam(configParam, buffer) == 0)
294 {
295 kumpf 1.2 if (buffer[0] == '/')
296 {
297 Strlcpy(path, buffer, sizeof(path));
298 break;
299 }
300 else if (GetHomedPath(buffer, buffer) == 0)
301 {
302 Strlcpy(path, buffer, sizeof(path));
303 break;
304 }
305 }
306
307 /* Just use the default value. */
308
309 if (GetHomedPath(defaultPath, buffer) == 0)
310 {
311 Strlcpy(path, buffer, sizeof(path));
312 break;
313 }
314
315 /* Failed. */
316 kumpf 1.2
317 status = -1;
318 }
319 while (0);
320
321 if (status == 0)
322 DefineMacro(configParam, path);
323
324 return status;
325 }
326
327 /*
328 **==============================================================================
329 **
330 ** DumpMacros()
331 **
332 ** Dump all macros to standard output.
333 **
334 **==============================================================================
335 */
336
337 kumpf 1.2 void DumpMacros()
338 {
339 const struct Macro* p;
340
341 printf("===== Macros:\n");
342
343 for (p = _macros; p; p = p->next)
344 printf("%s=%s\n", p->name, p->value);
345
346 putchar('\n');
347 }
|