⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cf.c

📁 The configuration file reading samples for ARM project development. Including the sample .conf files
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cf.h"

#define MAX_CONFIG_FILES            32
#define BUF_LENGTH                1024
#define CF_EMPTY_SLOT               -1

#define BEFORE_START                 0
#define EXAM_KEYWORD_APPEAR          1    /* examine keyword appearing in the line */
#define EXAM_BEGIN_APPEAR            2    /* examine BEGIN in the line             */
#define EXAM_END_APPEAR              3    /* examine END in the line               */
#define EXAM_CONTENT_AFTER_BEGIN     4    /* examine content line just leaving BEGIN */
#define EXAM_CONTENT_AS_KEYW_IS_NULL 5    /* examine content line of the current file position as the passed keyword is NULL */
#define SKIP_CURRENT_SECTION         6    /* skip the current section in case the keyword is not matched */
#define EXAM_END_TO_MATCH_BEGIN      7    /* examine END to match BEGIN within the skipped section */

#define CF_TRUE                      1
#define CF_FALSE                     0

typedef struct
{
  long fd;                        /* file descriptor */
  int fpos;                      /* file current position */
} cf_t;

static cf_t cf_array[MAX_CONFIG_FILES];
static int cf_array_init = 0;

static FILE * Config_fptr = (FILE *)NULL;


static int cf_new_index(long fd, int fpos);
static int cf_get_env_value(char *cptr,int buf_len,char *keyword, int *error);
char *cf_get_line(FILE *fptr, int *nofwords, int *error);
static int cf_match_token(char *cptr,char *text);

int CF_open(char *cf_path);
int CF_read(int cf_id, char *keyword, char *buf, int buf_len);
int CF_close(int cf_id);


/*
 * Open a configuration file
 *
 * flag indicator is used to check syntax of the  config file
 *              1 : EXAM_KEYWORD_APPEAR
 *              2 : EXAM_BEGIN_APPEAR
 *              3 : EXAM_END_APPEAR
 */

int
CF_open(char *cf_path)
{
  char *cptr;
  int nofwords = 0;
  int fpos, slot_index, err, flag = BEFORE_START, forever = 1 ;
  long fd;


  Config_fptr = fopen(cf_path,"r");

  if (Config_fptr == (FILE *)NULL)
    return (CF_NOT_FOUND);

  while (forever)
    {
       if ((cptr = cf_get_line(Config_fptr, &nofwords, &err)) == NULL)
         {
            if (err != CF_NOT_FOUND)
              {
                 fclose(Config_fptr);
                 return(err);
              }
            break;
         }
       if (flag == BEFORE_START)
           flag = EXAM_KEYWORD_APPEAR;          /* at beginning, assume keyword appear */

       switch (flag)
         {
            case (EXAM_KEYWORD_APPEAR):     /* expect KEYWORD appear */
              if (nofwords == 1)     /* one word in the line */
                {
			if (cf_match_token(cptr,"BEGIN") || cf_match_token(cptr,"END"))
                     {
                        fclose(Config_fptr);
                        return(CF_ERR_WITHOUT_KEYW);
                     }
                   flag = EXAM_BEGIN_APPEAR;         /*  assume BEGIN appear */
                }
              break;
            case (EXAM_BEGIN_APPEAR):       /* expect BEGIN appear */
              if (nofwords == 1)
                {
                   if (!cf_match_token(cptr,"BEGIN"))
                     {
                        fclose(Config_fptr);
                        return(CF_ERR_WITHOUT_BEGIN);
                     }
                   flag = EXAM_END_APPEAR;
                }
              else
                {
                   fclose(Config_fptr);
                   if (cf_match_token(cptr,"BEGIN"))
                     return(CF_ERR_BEGIN_DATA);
                   else
                     return(CF_ERR_WITHOUT_BEGIN);
                }
              break;
            case (EXAM_END_APPEAR):       /* expect END appear */
              if (nofwords == 1)
                {
                   if (cf_match_token(cptr,"END"))
                     flag = EXAM_KEYWORD_APPEAR;
                   if (cf_match_token(cptr,"BEGIN"))
                     {
                        fclose(Config_fptr);
                        return(CF_ERR_WITHOUT_END);
                     }
                }
         }
    }

   /*  handle syntax error
    *  normal case : flag = EXAM_KEYWORD_APPEAR; otherwise syntax error occurs
    */
  switch (flag)
    {
       case (BEFORE_START):
         fclose(Config_fptr);
         return(CF_NOT_FOUND);

       case (EXAM_BEGIN_APPEAR):
         fclose(Config_fptr);
         return(CF_ERR_WITHOUT_BEGIN);

       case (EXAM_END_APPEAR):
         fclose(Config_fptr);
         return(CF_ERR_WITHOUT_END);
    }


  fd = (long)Config_fptr;
  fpos = -1;
  slot_index = cf_new_index(fd,fpos);

  /* if no. of slots used reaches maximum, it returns error CF_ERR_SLOT_TOO_MANY.
   * otherwise one slot index is assigned to the CF opened
   */

  if (slot_index == CF_ERR_SLOT_TOO_MANY)
    {
       fclose(Config_fptr);
       return(CF_ERR_SLOT_TOO_MANY);
    }
  return (slot_index);
}


/*
 *  read a configuration file
 *  output : CF_OK - successfully read and buf contains the result
 *           otherwise returns error code
 */

int
CF_read(int cf_id, char *keyw, char *buf, int buf_len)
{
   int forever=1, nofwords=0, err=0, flag;
   char *cptr, *keyword;

   if (cf_id >= MAX_CONFIG_FILES || cf_id < 0)
     return (CF_ERR_PARAMETER);

   if (buf == NULL)
     return (CF_ERR_PARAMETER);

   if (buf_len > BUF_LENGTH || buf_len < 2 || buf_len == 0)
     return (CF_ERR_PARAMETER);

   Config_fptr = (FILE *)cf_array[cf_id].fd;
   keyword = keyw;

   if (keyword != NULL)
     {
        if (fseek(Config_fptr,0L,0))
          return (CF_ERR_FILE_POS);
        flag = EXAM_KEYWORD_APPEAR;
     }
   else
     {
        if (cf_array[cf_id].fpos == -1)
          return (CF_NOT_FOUND);

        if (fseek(Config_fptr, cf_array[cf_id].fpos, 0))
          return (CF_ERR_FILE_POS);
        flag = EXAM_CONTENT_AS_KEYW_IS_NULL;
     }


   while (forever)
     {
        if ((cptr = cf_get_line(Config_fptr, &nofwords, &err)) == NULL)
          return (err);

        switch (flag)
          {
             case (EXAM_KEYWORD_APPEAR):                    /* for matching KEYWORD */
               if (cf_match_token(cptr,keyword))
                 {
                    if (nofwords == 1)
                      {
                         flag = EXAM_BEGIN_APPEAR;
                         break;
                      }

                    if (cf_get_env_value(cptr,buf_len,keyword, &err))
                      {
                         strcpy(buf,cptr);
                         cf_array[cf_id].fpos = -1;
                         return (CF_OK);
                      }
                    else
                      return (err);
                 }
               else
                 {
                    if (nofwords == 1)
                      flag = SKIP_CURRENT_SECTION;     /* skip section */
                    break;
                 }
             case (EXAM_BEGIN_APPEAR):                       /* expect  BEGIN */
               if (cf_match_token(cptr,"BEGIN"))
                 {
                    flag = EXAM_CONTENT_AFTER_BEGIN;
                    break;
                 }
               return (CF_ERR_WITHOUT_BEGIN);

             case (EXAM_CONTENT_AFTER_BEGIN):                       /* just leaving BEGIN */
               if (cf_match_token(cptr,"END"))
                 return (CF_ERR_WITHOUT_DATA);

               if (cf_get_env_value(cptr,buf_len,keyword, &err))
                 {
                    strcpy(buf,cptr);
                    cf_array[cf_id].fpos = (int)ftell(Config_fptr);
                    return (CF_OK);
                 }
               else
                 return (err);

             case (EXAM_CONTENT_AS_KEYW_IS_NULL):                    /* As Keyword is passed as NULL */
               if (cf_match_token(cptr,"END"))
                 {
                    cf_array[cf_id].fpos = -1;
                    return (CF_NOT_FOUND);
                 }

               if (cf_get_env_value(cptr,buf_len,keyword, &err))
                 {
                    strcpy(buf,cptr);
                    cf_array[cf_id].fpos = (int)ftell(Config_fptr);
                    return (CF_OK);
                 }
               else
                 return (err);

             case (SKIP_CURRENT_SECTION):                   /* skip the section */
               if (cf_match_token(cptr,"BEGIN"))
                 {
                    flag = EXAM_END_TO_MATCH_BEGIN;
                    break;
                 }
               else
                 return (CF_ERR_WITHOUT_END);

             case (EXAM_END_TO_MATCH_BEGIN):                   /* jump to the next section for matching the KEYWORD */
               if (cf_match_token(cptr,"END"))
                 flag = EXAM_KEYWORD_APPEAR;
         }
     }
   return (CF_ERR_WITHOUT_DATA);
}



/*
 * close a configuration file
 */

int
CF_close(int cf_id)
{
  Config_fptr = (FILE *)cf_array[cf_id].fd;
  if (fclose(Config_fptr) == EOF)
     return (CF_ERR_CLOSE);

  Config_fptr = NULL;
  return (CF_OK);
}


/*
 *  Replace environment variable by its content in the input string
 *  Truncate the instring with the keyword and any spaces
 */

static int
cf_get_env_value(char *instring,int buf_len,char *keyword, int *err)
{
  int i, startvalue=0, pre_len, env_len, post_len, tot_len;
  char *dollar_bracket, *closing_bracket, *pre_str, *env_str, *env_val, *post_str;
  char tmp_line[BUF_LENGTH], env_cpy[BUF_LENGTH];

  if (keyword != NULL)
    {
       if (strncmp(instring,keyword,strlen(keyword)) == 0)
         startvalue = strlen(keyword);
    }

  for (i=startvalue; i<buf_len; i++)
    {
       if ( *(instring + i) != ' ' && *(instring + i) != '\t')
          break;
    }

  strcpy(instring,instring + i);

  while ((dollar_bracket = strstr(instring,"$(")) != NULL)
    {
       pre_str = instring;
       env_str = dollar_bracket + 2;

       if ((closing_bracket = strchr(env_str, ')')) == NULL)
         {
            *err = CF_ERR_SYNTAX_ENV;        /* bad enviornment valuable syntax format */
            return (CF_FALSE);
         }

       post_str = closing_bracket + 1;

       strncpy(env_cpy, env_str, (int) (closing_bracket - env_str));
       env_cpy[closing_bracket - env_str] = '\0';

       if ((env_val = getenv(env_cpy)) == (char *)NULL)
         {
            *err = CF_ERR_ENV_VAR;         /* no env variable set */
            return (CF_FALSE);
         }

       pre_len = (int) (dollar_bracket - pre_str);
       env_len = strlen(env_val);
       post_len = strlen(post_str);

       tot_len = pre_len + env_len + post_len + 1;
       if (tot_len > buf_len)
         {
            *err = CF_ERR_LINE_TOO_LONG;
            return (CF_FALSE);
         }
       *dollar_bracket = '\0';
       sprintf(tmp_line, "%s%s%s", pre_str,env_val,post_str);
       strncpy(instring, tmp_line, buf_len);
    }
  for (i=0; i<strlen(instring); i++)
    if (*(instring + i) == '\n')
      {
         *(instring + i) = '\0';
         break;
      }
  return (CF_TRUE);
}


/*
 * Function used to find whether the line contains the text pattern or not
 */

static int
cf_match_token(char *cptr, char *text)
{
  if (strncmp(cptr, text, strlen(text)) == 0)
     return (CF_TRUE);
  return (CF_FALSE);
}


/*
 * Get next free item index from the cf_array
 */

static int
cf_new_index(long fd, int fpos)
{
  int i;

  if (!cf_array_init)
    {
       for (i=0; i<MAX_CONFIG_FILES; i++)
          cf_array[i].fd = CF_EMPTY_SLOT;
       cf_array_init = 1;
    }

  for (i=0; i<MAX_CONFIG_FILES; i++)
     if (cf_array[i].fd == CF_EMPTY_SLOT)
       {
          cf_array[i].fd = fd;
          cf_array[i].fpos = fpos;
          return (i);
       }
  return (CF_ERR_SLOT_TOO_MANY);
}


/*
 *  Function to get one line from the config file, ignoring # remark line
 *  return values : pointer to char; the line content
 *  output parameters : nofwords ; no of words in the line
 *                      err ; error code
 */

char *
cf_get_line(FILE *fptr, int *nofwords, int *err)
{
  static char buf[BUF_LENGTH + 2];
  char *instring, c, previous=' ';
  int i, blank_first = 0, nofblanks=0, remflag;
  *nofwords = 0;

  instring = buf;
  while (fgets(instring, BUF_LENGTH, fptr) != NULL)
    {
       remflag = 0;
       for (i = 0; i < strlen(instring)-1; i++)
         {
           c = instring [i];
           if (c == ' ' || c == '\t')
             {
                if (i == 0)
                  blank_first = 1;
             }
           else if (c == '#' && *nofwords == 0 && (previous == ' ' || previous == '\t'))
             {
                blank_first = nofblanks = 0;
                remflag = 1;
                *nofwords = 0;
                break;
             }
           else
             {
               if (nofblanks == 0 && blank_first)
                 nofblanks = i;
               if (previous == ' ' || previous == '\t')
                 *nofwords = *nofwords + 1;
             }
           previous = c;
         }
       if (!remflag)
         {
           instring += nofblanks;
           return (instring);
         }
    }
  *err = CF_NOT_FOUND;
  return (NULL);
}













⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -