lib/getfilecontents.c
/* Read the file line by line and parse for comments, keys and values */
Read the file line by line and parse for comments, keys and values
Read the file line by line and parse for comments keys and values
econf_err
read_file(econf_file *ef, const char *file,
	  const char *delim, const char *comment)
{
  char buf[BUFSIZ];
  char *current_group = NULL;
  econf_err retval = ECONF_SUCCESS;
  uint64_t line = 0;
  bool has_wsp, has_nonwsp;
  FILE *kf = fopen(file, "rbe");
  if (kf == NULL)
    return ECONF_NOFILE;
  check_delim(delim, &has_wsp, &has_nonwsp);
  ef->path = strdup (file);
  if (ef->path == NULL) {
    fclose (kf);
    return ECONF_NOMEM;
  }
  ef->delimiter = *delim;
  while (fgets(buf, sizeof(buf), kf)) {
    char *p, *name, *data = NULL;
    bool quote_seen = false, delim_seen = false;
    line++;
    if (*buf == '\n')
      continue; 
    for (size_t i = 0; i < strlen(comment); i++) {
      p = strchr(buf, comment[i]);
      if (p)
	*p = '\0';
    }
    size_t n = strlen(buf);
    if (n && *(buf + n - 1) == '\n')
      *(buf + n - 1) = '\0';
    if (!*buf)
      continue;       
    name = buf;
    while (*name && isspace((unsigned)*name))
      name++;
    if (name[0] == '[') {
      p = name + strlen(name) - 1;
      while (isspace (*p)) p--;
      if (*p != ']') {
	retval = ECONF_PARSE_ERROR;
	goto out;
      }
      p++;
      *p = '\0';
      if (current_group)
	free (current_group);
      current_group = strdup (name);
      continue;
    }
    data = name;
    while (*data && !(isspace((unsigned)*data) ||
		      strchr(delim, *data) != NULL))
      data++;
    if (data > name && *data) {
      if (has_wsp && has_nonwsp)
	delim_seen = !isspace((unsigned)*data) &&
	  strchr(delim, *data) != NULL;
      else
	delim_seen = strchr(delim, *data) != NULL;
      *data++ = '\0';
    }
    if (!*name || data == name)
      continue;
    if (*data == '\0')
      data = NULL;
    else {
      while (*data && isspace((unsigned)*data))
	data++;
      if (!has_wsp && !delim_seen) {
	if (!*data || strchr(delim, *data) == NULL) {
	  retval = ECONF_PARSE_ERROR;
	  goto out;
	}
	data++;
	while (*data && isspace((unsigned)*data))
	  data++;
      } else if (has_wsp && has_nonwsp && !delim_seen &&
		 *data && strchr(delim, *data) != NULL) {
	data++;
	while (*data && isspace((unsigned)*data))
	  data++;
      }
      if (*data == '"') {
	quote_seen = true;
	data++;
      }
      p = data + strlen(data);
      if (p > data)
	p--;
      while (p > data && (isspace((unsigned)*p)))
	p--;
      if (p > data && quote_seen) {
	if (*p == '"')
	  p--;
	else
	  data--;
      }
      if (*(p + 1) != '\0')
	*(p + 1) = '\0';
    }
    retval = store(ef, current_group, name, data, line);
    if (retval)
      goto out;
  }
 out:
  fclose (kf);
  if (current_group)
    free (current_group);
  return retval;
}
econf_err read_file ( econf_file * ef , const char * file , const char * delim , const char * comment ) { char buf [ BUFSIZ ] ; char * current_group = NULL ; econf_err retval = ECONF_SUCCESS ; uint64_t line = 0 ; bool has_wsp , has_nonwsp ; FILE * kf = fopen ( file , " " ) ; if ( kf == NULL ) return ECONF_NOFILE ; check_delim ( delim , & has_wsp , & has_nonwsp ) ; ef -> path = strdup ( file ) ; if ( ef -> path == NULL ) { fclose ( kf ) ; return ECONF_NOMEM ; } ef -> delimiter = * delim ; while ( fgets ( buf , sizeof ( buf ) , kf ) ) { char * p , * name , * data = NULL ; bool quote_seen = false , delim_seen = false ; line ++ ; if ( * buf == ' \n ' ) continue ; for ( size_t i = 0 ; i < strlen ( comment ) ; i ++ ) { p = strchr ( buf , comment [ i ] ) ; if ( p ) * p = ' \0 ' ; } size_t n = strlen ( buf ) ; if ( n && * ( buf + n - 1 ) == ' \n ' ) * ( buf + n - 1 ) = ' \0 ' ; if ( ! * buf ) continue ; name = buf ; while ( * name && isspace ( ( unsigned ) * name ) ) name ++ ; if ( name [ 0 ] == ' ' ) { p = name + strlen ( name ) - 1 ; while ( isspace ( * p ) ) p -- ; if ( * p != ' ' ) { retval = ECONF_PARSE_ERROR ; goto out ; } p ++ ; * p = ' \0 ' ; if ( current_group ) free ( current_group ) ; current_group = strdup ( name ) ; continue ; } data = name ; while ( * data && ! ( isspace ( ( unsigned ) * data ) || strchr ( delim , * data ) != NULL ) ) data ++ ; if ( data > name && * data ) { if ( has_wsp && has_nonwsp ) delim_seen = ! isspace ( ( unsigned ) * data ) && strchr ( delim , * data ) != NULL ; else delim_seen = strchr ( delim , * data ) != NULL ; * data ++ = ' \0 ' ; } if ( ! * name || data == name ) continue ; if ( * data == ' \0 ' ) data = NULL ; else { while ( * data && isspace ( ( unsigned ) * data ) ) data ++ ; if ( ! has_wsp && ! delim_seen ) { if ( ! * data || strchr ( delim , * data ) == NULL ) { retval = ECONF_PARSE_ERROR ; goto out ; } data ++ ; while ( * data && isspace ( ( unsigned ) * data ) ) data ++ ; } else if ( has_wsp && has_nonwsp && ! delim_seen && * data && strchr ( delim , * data ) != NULL ) { data ++ ; while ( * data && isspace ( ( unsigned ) * data ) ) data ++ ; } if ( * data == ' ' ) { quote_seen = true ; data ++ ; } p = data + strlen ( data ) ; if ( p > data ) p -- ; while ( p > data && ( isspace ( ( unsigned ) * p ) ) ) p -- ; if ( p > data && quote_seen ) { if ( * p == ' ' ) p -- ; else data -- ; } if ( * ( p + 1 ) != ' \0 ' ) * ( p + 1 ) = ' \0 ' ; } retval = store ( ef , current_group , name , data , line ) ; if ( retval ) goto out ; } out : fclose ( kf ) ; if ( current_group ) free ( current_group ) ; return retval ; }
Read the file line by line and parse for comments, keys and values
Read the file line by line and parse for comments keys and values
/* ignore empty lines */ /* go throug all comment characters and check, if one of could be found */ /* Remove trailing newline character */ /* empty line */ /* ignore space at begin of the line */ /* check for groups */ /* XXX Remove [] around group name */ /* go to the end of the name */ /*
	 * delim contains both whitespace and non-whitespace characters.
	 * In this case delim_seen has the special meaning "non-whitespace
	 * delim seen". See comment below.
	 */ /* No seperator -> return NULL pointer, there is no value,
	 not even an empty key */ /* go to the begin of the value */ /*
	 * If delim consists only of non-whitespace characters,
	 * require at least one delimiter, and skip more whitespace
	 * after it.
	 */ /*
	 * If delim contains both whitespace and non-whitespace characters,
	 * use any combination of one non-whitespace delimiter and
	 * many whitespace delimiters as separator, but not multiple
	 * non-whitespace delimiters. Example with delim = " =":
	 * key value -> "value"
	 * key=value -> "value"
	 * key = value -> "value"
	 * key=  value -> "value"
	 * key == value -> "= value"
	 * key==value -> "=value"
	 */ /* remove space at the end of the value */ /* Strip double quotes only if both leading and trainling quote exist. */