home *** CD-ROM | disk | FTP | other *** search
/ CD-X 1 / cdx_01.iso / demodisc / basq / dualmodp / ini.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-02  |  5.8 KB  |  203 lines

  1. // ************************************************************************
  2. // *
  3. // *    File        : INI.C
  4. // *
  5. // *    Description : Config file routines
  6. // *
  7. // *    Copyright (C) 1993 Otto Chrons
  8. // *
  9. // ************************************************************************
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <malloc.h>
  14. #include <errno.h>
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17.  
  18. #pragma hdrstop
  19.  
  20. #include "ini.h"
  21.  
  22. int CurrentConfigLine;
  23.  
  24. ConfigItemData  C_DATA;
  25.  
  26. static void trimSpace(char *str)
  27. {
  28.     char    *orgStr = str;
  29.  
  30.     while( isspace(*str) ) str++;
  31.     strcpy(orgStr,str);
  32. }
  33.  
  34. int ReadConfig(char const *fileName, ConfigFile *c_file)
  35. {
  36.     FILE        *file;
  37.     ConfigClass *C_class = NULL;
  38.     ConfigItem  *C_item = NULL;
  39.     char        str[256],*str2 = NULL;
  40.     int         a;
  41.  
  42.     CurrentConfigLine = 0;
  43.     if( !c_file ) return EINVDAT;
  44.     c_file->firstClass = NULL;
  45.     c_file->currentClass = NULL;
  46.     if(( file = fopen(fileName,"rt")) == NULL) return ENOFILE;
  47.     if((c_file->fileName = _fullpath(NULL,fileName,0)) == NULL)
  48.     {
  49.         fclose(file);
  50.         return ENOMEM;
  51.     }
  52.     while( fgets(str,255,file) )
  53.     {
  54.         CurrentConfigLine++;            // Increase line counter, for error
  55.                                         // tracking
  56.         if( strlen(str) > 250 )         // is the line too long?
  57.         {
  58.             fclose(file);
  59.             return EINVDAT;
  60.         }
  61.         trimSpace(str);
  62.         strrev(str);
  63.         trimSpace(str);
  64.         strrev(str);
  65.         if( strlen(str) < 3 ) continue;
  66.         if( *str == ';' ) continue;     // Comment
  67.         if( *str == '[' )               // New class
  68.         {
  69.             str2 = strchr(str+1,']');
  70.             if( !str2 ) continue;       // Valid class?
  71.             if( C_class )               // Is it the first?
  72.             {
  73.                                         // No, create a new class and link it
  74.                 if((C_class->nextClass = malloc(sizeof(ConfigClass))) == NULL)
  75.                 {
  76.                     fclose(file);
  77.                     return ENOMEM;
  78.                 }
  79.                 C_class = C_class->nextClass;
  80.             } else                      // Yes, create and add to config file
  81.             {
  82.                 if((C_class = malloc(sizeof(ConfigClass))) == NULL)
  83.                 {
  84.                     fclose(file);
  85.                     return ENOMEM;
  86.                 }
  87.                 c_file->firstClass = C_class;
  88.             }
  89.             C_item = NULL;
  90.             C_class->nextClass = NULL;
  91.             C_class->firstItem = NULL;
  92.             a = ((str2-str-1 < 31) ? str2-str-1 : 31);
  93.             if( a == 0 )
  94.             {
  95.                 fclose(file);
  96.                 return EINVDAT;
  97.             }
  98.             strncpy(C_class->name,str+1,a);
  99.             C_class->name[a] = 0;       // Terminate string
  100.             trimSpace(C_class->name);
  101.             strrev(C_class->name);
  102.             trimSpace(C_class->name);
  103.             strrev(C_class->name);
  104.         }
  105.         else
  106.         {
  107.             if( C_class == NULL ) continue;
  108.             str2 = strchr(str,'=');     // Seek '='
  109.             if( str2 == NULL ) continue;
  110.             if( C_item )
  111.             {
  112.                 if((C_item->nextItem = malloc(sizeof(ConfigItem))) == NULL)
  113.                 {
  114.                     fclose(file);
  115.                     return ENOMEM;
  116.                 }
  117.                 C_item = C_item->nextItem;
  118.             } else
  119.             {
  120.                 if((C_item = malloc(sizeof(ConfigItem))) == NULL)
  121.                 {
  122.                     fclose(file);
  123.                     return ENOMEM;
  124.                 }
  125.                 C_class->firstItem = C_item;
  126.             }
  127.             C_item->nextItem = NULL;
  128.             if((C_item->data = malloc(strlen(str2+1)+1)) == NULL)
  129.             {
  130.                 fclose(file);
  131.                 return ENOMEM;
  132.             }
  133.             strcpy(C_item->data,str2+1);
  134.             trimSpace(C_item->data);
  135.             *str2 = 0;                  // Strip the data part
  136.             strncpy(C_item->name,str,31);
  137.             C_item->name[31] = 0;
  138.             strrev(C_item->name);
  139.             trimSpace(C_item->name);
  140.             strrev(C_item->name);
  141.         }
  142.     }
  143.     fclose(file);
  144.     return 0;
  145. }
  146.  
  147. ConfigItemData *GetConfigItem(char const *itemName, enum ConfigDataType type, ConfigFile *c_file)
  148. {
  149.     ConfigClass *c = c_file->currentClass;
  150.     ConfigItem  *i;
  151.  
  152.     if( c == NULL ) return NULL;    // Is there a current class selection?
  153.     i = c->firstItem;
  154.     while( i != NULL && stricmp(itemName,i->name) ) // Search for itemName
  155.     {
  156.         i = i->nextItem;
  157.     }
  158.     if( i == NULL ) return NULL;
  159.     switch( type )
  160.     {
  161.         case T_STR :
  162.             C_DATA.i_str = i->data;
  163.             break;
  164.         case T_BOOL :
  165.             C_DATA.i_bool = FALSE;
  166.             if( atol(i->data) == 1 ) C_DATA.i_bool = TRUE;
  167.             if( stricmp(i->data,"yes") == 0 ||
  168.                 stricmp(i->data,"ok") == 0 ||
  169.                 stricmp(i->data,"y") == 0 ||
  170.                 stricmp(i->data,"true") == 0) C_DATA.i_bool = TRUE;
  171.             break;
  172.         case T_LONG :
  173.             C_DATA.i_long = strtol(i->data,NULL,0);
  174.             break;
  175.         default:
  176.             return NULL;
  177.     }
  178.     return &C_DATA;
  179. }
  180.  
  181. int SelectConfigClass(char const *className, ConfigFile *c_file)
  182. {
  183.     ConfigClass    *cPtr;
  184.  
  185.     if( !c_file ) return 0;
  186.     if(( cPtr = GetConfigClass( className, c_file )) == NULL) return 0;
  187.     c_file->currentClass = cPtr;
  188.     return 1;
  189. }
  190.  
  191. ConfigClass *GetConfigClass(char const *className, ConfigFile *c_file)
  192. {
  193.     ConfigClass *c = c_file->firstClass;
  194.  
  195.     if( !c_file ) return NULL;
  196.  
  197.     while( c != NULL && stricmp(className,c->name) )
  198.     {
  199.     c = c->nextClass;
  200.     }
  201.     return c;
  202. }
  203.