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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2