(file) Return to Macro.c CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Executor

  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 dmitry.mikulin 1.4         {
 93 kumpf          1.2             return p->value;
 94 dmitry.mikulin 1.4         }
 95 kumpf          1.2     }
 96                    
 97                        /* Not found. */
 98                        return NULL;
 99                    }
100                    
101                    /*
102                    **==============================================================================
103                    **
104                    ** DefineMacro()
105                    **
106                    **     Add a new macro to the macro list.
107                    **
108                    **==============================================================================
109                    */
110                    
111                    int DefineMacro(const char* name, const char* value)
112                    {
113                        struct Macro* macro;
114                    
115                        /* Reject if the macro is already defined. */
116 kumpf          1.2 
117                        if (FindMacro(name) != NULL)
118 dmitry.mikulin 1.4     {
119 kumpf          1.2         return -1;
120 dmitry.mikulin 1.4     }
121 kumpf          1.2 
122                        /* Create new macro. */
123                    
124 dmitry.mikulin 1.4     if ((macro = (struct Macro*)malloc(sizeof(struct Macro))) == NULL)
125                        {
126                            return -1;
127                        }
128 kumpf          1.2     macro->name = strdup(name);
129                        macro->value = strdup(value);
130                    
131                        /* Add to end of list. */
132                    
133                        {
134                            struct Macro* p;
135                            struct Macro* prev = NULL;
136                    
137                            for (p = _macros; p; p = p->next)
138 dmitry.mikulin 1.4         {
139 kumpf          1.2             prev = p;
140 dmitry.mikulin 1.4         }
141 kumpf          1.2 
142                            if (prev)
143 dmitry.mikulin 1.4         {
144 kumpf          1.2             prev->next = macro;
145 dmitry.mikulin 1.4         }
146 kumpf          1.2         else
147 dmitry.mikulin 1.4         {
148 kumpf          1.2             _macros = macro;
149 dmitry.mikulin 1.4         }
150 kumpf          1.2 
151                            macro->next = NULL;
152                        }
153                    
154                        return 0;
155                    }
156                    
157                    /*
158                    **==============================================================================
159                    **
160                    ** UndefineMacro()
161                    **
162                    **     Remove the given macro from the macro table.
163                    **
164                    **==============================================================================
165                    */
166                    
167                    int UndefineMacro(const char* name)
168                    {
169                        struct Macro* p;
170                        struct Macro* prev;
171 kumpf          1.2 
172                        for (p = _macros, prev = 0; p; p = p->next)
173                        {
174                            if (strcmp(p->name, name) == 0)
175                            {
176                                if (prev)
177 dmitry.mikulin 1.4             {
178 kumpf          1.2                 prev->next = p->next;
179 dmitry.mikulin 1.4             }
180 kumpf          1.2             else
181 dmitry.mikulin 1.4             {
182 kumpf          1.2                 _macros = p->next;
183 dmitry.mikulin 1.4             }
184 kumpf          1.2 
185                                free(p->name);
186                                free(p->value);
187                                free(p);
188                                return 0;
189                            }
190                    
191                            prev = p;
192                        }
193                    
194                        /* Not found. */
195                        return -1;
196                    }
197                    
198                    /*
199                    **==============================================================================
200                    **
201                    ** ExpandMacros()
202                    **
203                    **     Expand all macros in *input*. Leave result in *output*.
204                    **
205 kumpf          1.2 **==============================================================================
206                    */
207                    
208                    int ExpandMacros(const char* input, char output[EXECUTOR_BUFFER_SIZE])
209                    {
210                        char buffer[EXECUTOR_BUFFER_SIZE];
211                        char* p;
212                    
213                        /* Make copy of input since we'll need to destroy it. */
214                    
215                        Strlcpy(buffer, input, sizeof(buffer));
216                        output[0] = '\0';
217                    
218                        /* Traverse buffer, copying characters and expanding macros as we go. */
219                    
220                        for (p = buffer; *p; )
221                        {
222                            /* Look for start of macro. */
223                    
224                            if (p[0] == '$' && p[1] == '{')
225                            {
226 kumpf          1.2             char* q;
227                    
228                                /* Set p and q as follows.
229                                 *
230                                 *       p       q
231                                 *       |       |
232                                 *       v       v
233                                 * "...${MY_MACRO}..."
234                                 */
235                    
236                                p += 2;
237                    
238                                /* Find end of macro. */
239                    
240                                for (q = p; *q && *q != '}'; q++)
241                                    ;
242                    
243                                if (*q != '}')
244                                {
245                                    Log(LL_SEVERE, "ExpandMacros(): corrupt input: %s", input);
246                                    return -1;
247 kumpf          1.2             }
248                    
249                                /* Replace '}' with null-terminator. */
250                    
251                                *q = '\0';
252                    
253                                /* Lookup macro and append value. */
254                    
255                                {
256                                    const char* value;
257                                    value = FindMacro(p);
258                    
259                                    if (!value)
260                                    {
261                                        Log(LL_SEVERE, "ExpandMacros(): Undefined macro: %s", p);
262                                        return -1;
263                                    }
264                    
265                                    Strlcat(output, value, EXECUTOR_BUFFER_SIZE);
266                                }
267                    
268 kumpf          1.2             p = q + 1;
269                            }
270                            else
271                            {
272                                /* Append current character to output. */
273                    
274                                char two[2];
275                                two[0] = *p++;
276                                two[1] = '\0';
277                    
278                                Strlcat(output, two, EXECUTOR_BUFFER_SIZE);
279                            }
280                        }
281                    
282                        return 0;
283                    }
284                    
285                    /*
286                    **==============================================================================
287                    **
288                    ** DefineConfigPathMacro()
289 kumpf          1.2 **
290                    **     Define a new path macro whose value is taken from the given
291                    **     configuration parameter. If no such configuration parameter is defined,
292                    **     use the defaultPath.
293                    **
294                    **==============================================================================
295                    */
296                    
297                    int DefineConfigPathMacro(const char* configParam, const char* defaultPath)
298                    {
299                        char path[EXECUTOR_BUFFER_SIZE];
300                        int status;
301                    
302                        status = 0;
303                    
304                        do
305                        {
306                            char buffer[EXECUTOR_BUFFER_SIZE];
307                    
308                            /* First try to get value from configuration. */
309                    
310 kumpf          1.2         if (GetConfigParam(configParam, buffer) == 0)
311                            {
312                                if (buffer[0] == '/')
313                                {
314                                    Strlcpy(path, buffer, sizeof(path));
315                                    break;
316                                }
317                                else if (GetHomedPath(buffer, buffer) == 0)
318                                {
319                                    Strlcpy(path, buffer, sizeof(path));
320                                    break;
321                                }
322                            }
323                    
324                            /* Just use the default value. */
325                    
326                            if (GetHomedPath(defaultPath, buffer) == 0)
327                            {
328                                Strlcpy(path, buffer, sizeof(path));
329                                break;
330                            }
331 kumpf          1.2 
332                            /* Failed. */
333                    
334                            status = -1;
335                        }
336                        while (0);
337                    
338                        if (status == 0)
339 dmitry.mikulin 1.4     {
340 kumpf          1.2         DefineMacro(configParam, path);
341 dmitry.mikulin 1.4     }
342 kumpf          1.2 
343                        return status;
344                    }
345                    
346                    /*
347                    **==============================================================================
348                    **
349                    ** DumpMacros()
350                    **
351                    **     Dump all macros to standard output.
352                    **
353                    **==============================================================================
354                    */
355                    
356 kumpf          1.3 void DumpMacros(FILE* outputStream)
357 kumpf          1.2 {
358                        const struct Macro* p;
359                    
360 kumpf          1.3     fprintf(outputStream, "===== Macros:\n");
361 kumpf          1.2 
362                        for (p = _macros; p; p = p->next)
363 dmitry.mikulin 1.4     {
364 kumpf          1.3         fprintf(outputStream, "%s=%s\n", p->name, p->value);
365 dmitry.mikulin 1.4     }
366 kumpf          1.2 
367 kumpf          1.3     putc('\n', outputStream);
368 kumpf          1.2 }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2