?? cf.c
字號(hào):
#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);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -