(file) Return to regfile.c CVS log (file) (dir) Up to [OMI] / omi / provreg

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           #include <stdio.h>
 26           #include <ctype.h>
 27           #include <base/strings.h>
 28           #include <base/list.h>
 29           #include <base/io.h>
 30           #include "regfile.h"
 31           
 32           // Parse an identifies of the form "[A-Za-z_][A-Za-z_0-9]*"
 33           static int _ParseIdentifier(char** pOut, char** start, char** end)
 34           {
 35               char* p = *pOut;
 36           
 37               /* Skip leading whitespace */
 38               while (isspace((unsigned char)(*p)))
 39                   p++;
 40           
 41               /* Set start of identifier */
 42               *start = p;
 43 mike  1.1 
 44               /* Expect [A-Za-z_] characters */
 45               if (!isalpha((unsigned char)(*p)) && *p != '_')
 46                   return -1;
 47           
 48               /* Skip [A-Za-z_0-9] characters */
 49               while (isalnum((unsigned char)(*p)) || *p == '_')
 50                   p++;
 51           
 52               /* Set end of identifier */
 53               *end = p;
 54           
 55               *pOut = p;
 56               return 0;
 57           }
 58           
 59           // Parase class path of the form "CLASS1:CLASS2:CLASS3"
 60           static int _ParseClassPath(char** pOut, char** start, char** end)
 61           {
 62               char* p = *pOut;
 63           
 64 mike  1.1     /* Skip leading whitespace */
 65               while (isspace((unsigned char)(*p)))
 66                   p++;
 67           
 68               /* Set start of identifier */
 69               *start = p;
 70           
 71               /* Expect [A-Za-z_] characters */
 72               if (!isalpha((unsigned char)(*p)) && *p != '_')
 73                   return -1;
 74           
 75               /* Skip [A-Za-z_0-9] characters */
 76               while (isalnum((unsigned char)(*p)) || *p == '_' || *p == ':')
 77                   p++;
 78           
 79               /* Set end of identifier */
 80               *end = p;
 81           
 82               *pOut = p;
 83               return 0;
 84           }
 85 mike  1.1 
 86           static int _ExpectChar(char** pOut, char ch)
 87           {
 88               char* p = *pOut;
 89           
 90               /* Skip whitespace */
 91               while (isspace((unsigned char)(*p)))
 92                   p++;
 93           
 94               /* Expect character */
 95               if (*p != ch)
 96                   return -1;
 97               p++;
 98           
 99               *pOut = p;
100               return 0;
101           }
102           
103           // Parse a line of the form 'KEY=VALUE'
104           static int _ParseKeyValueLine(char** pOut, char** keyOut, char** valueOut)
105           {
106 mike  1.1     char* p = *pOut;
107               char* keyEnd;
108           
109               /* Parse key */
110               if (_ParseIdentifier(&p, keyOut, &keyEnd) != 0)
111                   return-1;
112           
113               /* If out of input, error out */
114               if (!*p)
115                   return -1;
116           
117               /* Skip whitespace */
118               if (_ExpectChar(&p, '=') != 0)
119                   return -1;
120           
121               /* Null-terminate the key */
122               *keyEnd = '\0';
123           
124               /* Skip whitespace */
125               while (isspace((unsigned char)(*p)))
126                   p++;
127 mike  1.1 
128               /* Set value */
129               *valueOut = p;
130           
131               *pOut = p;
132               return 0;
133           }
134           
135           static int _ParseClassValue(
136               char** pOut, 
137               char** nameOut, 
138               char** refName1Out,
139               char** refName2Out)
140           {
141               char* p = *pOut;
142               char* start;
143               char* end;
144           
145               /* Expect class name */
146               if (_ParseClassPath(&p, &start, &end) != 0)
147                   return -1;
148 mike  1.1 
149               /* Skip whitespace */
150               while (isspace((unsigned char)(*p)))
151                   p++;
152           
153               /* If end of line */
154               if (!*p)
155               {
156                   *nameOut = start;
157                   *end = '\0';
158                   *refName1Out = NULL;
159                   *refName2Out = NULL;
160                   *pOut = p;
161                   return 0;
162               }
163           
164               /* Expect '{' character */
165               if (_ExpectChar(&p, '{') != 0)
166                   return -1;
167           
168               /* Get 'name' */
169 mike  1.1     *nameOut = start;
170               *end = '\0';
171           
172               /* Expect reference name */
173               if (_ParseClassPath(&p, &start, &end) != 0)
174                   return -1;
175           
176               /* Expect ',' character */
177               if (_ExpectChar(&p, ',') != 0)
178                   return -1;
179           
180               /* Get 'refName1' */
181               *refName1Out = start;
182               *end = '\0';
183           
184               /* Expect reference name */
185               if (_ParseClassPath(&p, &start, &end) != 0)
186                   return -1;
187           
188               /* Expect '}' character */
189               if (_ExpectChar(&p, '}') != 0)
190 mike  1.1         return -1;
191           
192               /* Get 'refName1' */
193               *refName2Out = start;
194               *end = '\0';
195           
196               *pOut = p;
197               return 0;
198           }
199           
200           RegFile* RegFile_New(const char* path)
201           {
202               FILE* is;
203               char buf[1024];
204               int foundLibrary = 0;
205               char* hosting = NULL;
206           
207               RegFile* self = 0;
208           
209               /* Open the file */
210               is = Fopen(path, "rb");
211 mike  1.1     if (!is)
212                   return NULL;
213           
214               /* Allocate self structure */
215               self = (RegFile*)calloc(1, sizeof(RegFile));
216               if (!self)
217               {
218                   fclose(is);
219                   return NULL;
220               }
221           
222               /* Read line by line */
223               while (fgets(buf, sizeof(buf), is) != NULL)
224               {
225                   char* start = buf;
226                   char* p = start;
227                   char* key;
228                   char* value;
229           
230                   /* Skip comment lines */
231                   if (*p == '#')
232 mike  1.1             continue;
233           
234                   /* Remove trailing whitespace */
235                   {
236                       char* end = buf + strlen(buf);
237           
238                       while (end != start && isspace((unsigned char)end[-1]))
239                           *--end = '\0';
240                   }
241           
242                   /* Skip leading whitespace */
243                   while (isspace((unsigned char)(*p)))
244                       p++;
245           
246                   /* Skip blank lines */
247                   if (*p == '\0')
248                       continue;
249           
250                   /* Look for LIBRARY= */
251                   if (_ParseKeyValueLine(&p, &key, &value) != 0)
252                       goto failed;
253 mike  1.1 
254                   if (strcmp(key, "LIBRARY") == 0)
255                   {
256                       if (foundLibrary)
257                           goto failed;
258           
259                       self->library = Strdup(value);
260           
261                       if (!self->library)
262                           goto failed;
263           
264                       foundLibrary = 1;
265                   }
266                   else if (strcmp(key, "HOSTING") == 0)
267                   {
268                       if (hosting)
269                           free(hosting);
270           
271                       hosting = Strdup(value);
272                   }
273                   else if (strcmp(key, "CLASS") == 0)
274 mike  1.1         {
275                       char* name;
276                       char* refName1;
277                       char* refName2;
278                       RegClass* rc;
279           
280                       if (_ParseClassValue(&p, &name, &refName1, &refName2) != 0)
281                           goto failed;
282           
283                       rc = (RegClass*)calloc(1, sizeof(RegClass));
284                       if (!rc)
285                           goto failed;
286           
287                       List_Append(
288                           (ListElem**)&self->classesHead,
289                           (ListElem**)&self->classesTail,
290                           (ListElem*)rc);
291           
292                       rc->name = Strdup(name);
293                       if (!rc->name)
294                           goto failed;
295 mike  1.1 
296                       if (refName1)
297                       {
298                           rc->refName1 = Strdup(refName1);
299                           if (!rc->refName1)
300                               goto failed;
301                       }
302           
303                       if (refName2)
304                       {
305                           rc->refName2 = Strdup(refName2);
306                           if (!rc->refName2)
307                               goto failed;
308                       }
309           
310                       if (hosting)
311                           rc->hosting = Strdup(hosting);
312                   }
313               }
314           
315               if (hosting)
316 mike  1.1         free(hosting);
317           
318               fclose(is);
319           
320               return self;
321           
322           failed:
323               if (self)
324                   RegFile_Delete(self);
325           
326               if (is)
327                   fclose(is);
328           
329               return NULL;
330           }
331           
332           void RegFile_Delete(RegFile* self)
333           {
334               RegClass* rc;
335               RegClass* next;
336           
337 mike  1.1     if (!self)
338                   return;
339           
340               if (self->library)
341                   free(self->library);
342           
343               for (rc = self->classesHead; rc; rc = next)
344               {
345                   if (rc->name)
346                       free(rc->name);
347           
348                   if (rc->refName1)
349                       free(rc->refName1);
350           
351                   if (rc->refName2)
352                       free(rc->refName2);
353           
354                   if (rc->hosting)
355                       free(rc->hosting);
356           
357                   next = rc->next;
358 mike  1.1         free(rc);
359               }
360           
361               free(self);
362           }
363           
364           void RegFile_Print(RegFile* self, FILE* os)
365           {
366               RegClass* rc;
367           
368               fprintf(os, "LIBRARY=%s\n", self->library);
369           
370               for (rc = self->classesHead; rc; rc = rc->next)
371               {
372                   fprintf(os, "CLASS=%s", rc->name);
373           
374                   if (rc->refName1 && rc->refName2)
375                   {
376                       fprintf(os, "{");
377                       fprintf(os, "%s", rc->refName1);
378                       fprintf(os, ",");
379 mike  1.1             fprintf(os, "%s", rc->refName2);
380                       fprintf(os, "}");
381                   }
382           
383                   fprintf(os, "\n");
384               }
385           }

ViewCVS 0.9.2