/*****************************************************************************\
 *  parse_config.c - parse any slurm.conf-like configuration file
 *
 *  NOTE: when you see the prefix "s_p_", think "slurm parser".
 *
 *  $Id$
 *****************************************************************************
 *  Copyright (C) 2006 The Regents of the University of California.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Christopher J. Morrone <morrone2@llnl.gov>.
 *  UCRL-CODE-226842.
 *  
 *  This file is part of SLURM, a resource management program.
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 *  
 *  SLURM is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission 
 *  to link the code of portions of this program with the OpenSSL library under 
 *  certain conditions as described in each individual source file, and 
 *  distribute linked combinations including the two. You must obey the GNU 
 *  General Public License in all respects for all of the code used other than 
 *  OpenSSL. If you modify file(s) with this exception, you may extend this 
 *  exception to your version of the file(s), but you are not obligated to do 
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in 
 *  the program, then also delete it here.
 *  
 *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *  
 *  You should have received a copy of the GNU General Public License along
 *  with SLURM; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>

/* #include "src/common/slurm_protocol_defs.h" */
#include "src/common/log.h"
#include "src/common/macros.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"
#include "src/common/xassert.h"
/* #include "src/common/slurm_rlimits_info.h" */
#include "src/common/parse_config.h"

#include <slurm/slurm.h>

#define BUFFER_SIZE 4096

#define CONF_HASH_LEN 26

static regex_t keyvalue_re;
static char *keyvalue_pattern =
	"^[[:space:]]*"
	"([[:alpha:]]+)" /* key */
	"[[:space:]]*=[[:space:]]*"
	"((\"([^\"]*)\")|([^[:space:]]+))" /* value: quoted with whitespace,
					    * or unquoted and no whitespace */
	"([[:space:]]|$)";
static bool keyvalue_initialized = false;

struct s_p_values {
	char *key;
	int type;
	int data_count;
	void *data;
	int (*handler)(void **data, slurm_parser_enum_t type,
		       const char *key, const char *value,
		       const char *line, char **leftover);
	void (*destroy)(void *data);
	s_p_values_t *next;
};

/*
 * NOTE - "key" is case insensitive.
 */
static int _conf_hashtbl_index(const char *key)
{
	int i;
	int idx = 0;

	xassert(key);
	for (i = 0; i < 10; i++) {
		if (key[i] == '\0')
			break;
		idx += tolower(key[i]);
	}
	return idx % CONF_HASH_LEN;
}

static void _conf_hashtbl_insert(s_p_hashtbl_t *hashtbl,
				 s_p_values_t *value)
{
	int idx;

	xassert(value);
	idx = _conf_hashtbl_index(value->key);
	value->next = hashtbl[idx];
	hashtbl[idx] = value;
}

/*
 * NOTE - "key" is case insensitive.
 */
static s_p_values_t *_conf_hashtbl_lookup(
	const s_p_hashtbl_t *hashtbl, const char *key)
{
	int idx;
	s_p_values_t *p;

	xassert(key);
	if (hashtbl == NULL)
		return NULL;

	idx = _conf_hashtbl_index(key);
	for (p = hashtbl[idx]; p != NULL; p = p->next) {
		if (strcasecmp(p->key, key) == 0)
			return p;
	}
	return NULL;
}

s_p_hashtbl_t *s_p_hashtbl_create(
	s_p_options_t options[])
{
	s_p_options_t *op = NULL;
	s_p_values_t *value = NULL;
	s_p_hashtbl_t *hashtbl = NULL;
	int len;

	len = CONF_HASH_LEN * sizeof(s_p_values_t *);
	hashtbl = (s_p_hashtbl_t *)xmalloc(len);
	memset(hashtbl, 0, len);
					      
	for (op = options; op->key != NULL; op++) {
		value = xmalloc(sizeof(s_p_values_t));
		value->key = xstrdup(op->key);
		value->type = op->type;
		value->data_count = 0;
		value->data = NULL;
		value->next = NULL;
		value->handler = op->handler;
		value->destroy = op->destroy;
		_conf_hashtbl_insert(hashtbl, value);
	}

	return hashtbl;
}

static void _conf_file_values_free(s_p_values_t *p)
{
	int i;

	if (p->data_count > 0) {
		switch(p->type) {
		case S_P_ARRAY:
			for (i = 0; i < p->data_count; i++) {
				void **ptr_array = (void **)p->data;
				if (p->destroy != NULL) {
					p->destroy(ptr_array[i]);
				} else {
					xfree(ptr_array[i]);
				}
			}
			xfree(p->data);
			break;
		default:
			if (p->destroy != NULL) {
				p->destroy(p->data);
			} else {
				xfree(p->data);
			}
			break;
		}
	}
	xfree(p->key);
	xfree(p);
}

void s_p_hashtbl_destroy(s_p_hashtbl_t *hashtbl) {
	int i;
	s_p_values_t *p, *next;

	for (i = 0; i < CONF_HASH_LEN; i++) {
		for (p = hashtbl[i]; p != NULL; p = next) {
			next = p->next;
			_conf_file_values_free(p);
		}
	}
	xfree(hashtbl);
}

static void _keyvalue_regex_init(void)
{
	if (!keyvalue_initialized) {
		if (regcomp(&keyvalue_re, keyvalue_pattern,
			    REG_EXTENDED) != 0) {
			/* FIXME - should be fatal? */
			error("keyvalue regex compilation failed\n");
		}
		keyvalue_initialized = true;
	}
}

/*
 * IN line - string to be search for a key=value pair
 * OUT key - pointer to the key string (caller must free with xfree())
 * OUT value - pointer to the value string (caller must free with xfree())
 * OUT remaining - pointer into the "line" string denoting the start
 *                 of the unsearched portion of the string
 * Return 0 when a key-value pair is found, and -1 otherwise.
 */
static int _keyvalue_regex(const char *line,
			   char **key, char **value, char **remaining)
{
	size_t nmatch = 8;
	regmatch_t pmatch[8];

	*key = NULL;
	*value = NULL;
	*remaining = (char *)line;
	memset(pmatch, 0, sizeof(regmatch_t)*nmatch);
	if (regexec(&keyvalue_re, line, nmatch, pmatch, 0)
	    == REG_NOMATCH) {
		return -1;
	}

	*key = (char *)(xstrndup(line + pmatch[1].rm_so,
				 pmatch[1].rm_eo - pmatch[1].rm_so));


	if (pmatch[4].rm_so != -1) {
		*value = (char *)(xstrndup(line + pmatch[4].rm_so,
					   pmatch[4].rm_eo - pmatch[4].rm_so));
	} else if (pmatch[5].rm_so != -1) {
		*value = (char *)(xstrndup(line + pmatch[5].rm_so,
					   pmatch[5].rm_eo - pmatch[5].rm_so));
	} else {
		*value = xstrdup("");
	}

	*remaining = (char *)(line + pmatch[2].rm_eo);

	return 0;
}

static int _strip_continuation(char *buf, int len)
{
	char *ptr;
	int bs = 0;

	for (ptr = buf+len-1; ptr >= buf; ptr--) {
		if (*ptr == '\\')
			bs++;
		else if (isspace(*ptr) && bs == 0)
			continue;
		else
			break;
	}
	/* Check for an odd number of contiguous backslashes at
	   the end of the line */
	if (bs % 2 == 1) {
		ptr = ptr + bs;
		*ptr = '\0';
		return (ptr - buf);
	} else {
		return len; /* no continuation */
	}
}

/*
 * Strip out trailing carriage returns and newlines
 */
static void _strip_cr_nl(char *line)
{
	int len = strlen(line);
	char *ptr;

	for (ptr = line+len-1; ptr >= line; ptr--) {
		if (*ptr=='\r' || *ptr=='\n') {
			*ptr = '\0';
		} else {
			return;
		}
	}
}

/* Strip comments from a line by terminating the string
 * where the comment begins.
 * Everything after a non-escaped "#" is a comment.
 */
static void _strip_comments(char *line)
{
	int i;
	int len = strlen(line);
	int bs_count = 0;

	for (i = 0; i < len; i++) {
		/* if # character is preceded by an even number of
		 * escape characters '\' */
		if (line[i] == '#' && (bs_count%2) == 0) {
			line[i] = '\0';
 			break;
		} else if (line[i] == '\\') {
			bs_count++;
		} else {
			bs_count = 0;
		}
	}
}

/*
 * Strips any escape characters, "\".  If you WANT a back-slash,
 * it must be escaped, "\\".
 */
static void _strip_escapes(char *line)
{
	int i, j;
	int len = strlen(line);

	for (i = 0, j = 0; i < len+1; i++, j++) {
		if (line[i] == '\\')
			i++;
		line[j] = line[i];
	}
}

/*
 * Reads the next line from the "file" into buffer "buf".
 *
 * Concatonates together lines that are continued on
 * the next line by a trailing "\".  Strips out comments,
 * replaces escaped "\#" with "#", and replaces "\\" with "\".
 */
static int _get_next_line(char *buf, int buf_size, FILE *file)
{
	char *ptr = buf;
	int leftover = buf_size;
	int read_size, new_size;
	int lines = 0;

	while (fgets(ptr, leftover, file)) {
		lines++;
		_strip_comments(ptr);
		read_size = strlen(ptr);
		new_size = _strip_continuation(ptr, read_size);
		if (new_size < read_size) {
			ptr += new_size;
			leftover -= new_size;
		} else { /* no continuation */
			break;
		}
	}
	/* _strip_cr_nl(buf); */ /* not necessary */
	_strip_escapes(buf);
	
	return lines;
}

static int _handle_string(s_p_values_t *v,
			  const char *value, const char *line, char **leftover)
{
	if (v->data_count != 0) {
		debug("%s specified more than once", v->key);
		xfree(v->data);
		v->data_count = 0;
	}

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		v->data = xstrdup(value);
	}

	v->data_count = 1;
	return 1;
}

static int _handle_long(s_p_values_t *v,
			const char *value, const char *line, char **leftover)
{
	if (v->data_count != 0) {
		debug("%s specified more than once", v->key);
		xfree(v->data);
		v->data_count = 0;
	}

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		char *endptr;
		long num;
		errno = 0;
		num = strtol(value, &endptr, 0);
		if ((num == 0 && errno == EINVAL)
		    || (*endptr != '\0')) {
			if (strcasecmp(value, "UNLIMITED") == 0
			    || strcasecmp(value, "INFINITE") == 0) {
				num = (long)-1;
			} else {
				error("\"%s\" is not a valid number", value);
				return -1;
			}
		} else if (errno == ERANGE) {
			error("\"%s\" is out of range", value);
			return -1;
		}
		v->data = xmalloc(sizeof(long));
		*(long *)v->data = num;
	}

	v->data_count = 1;
	return 1;
}

static int _handle_uint16(s_p_values_t *v,
			  const char *value, const char *line, char **leftover)
{
	if (v->data_count != 0) {
		debug("%s specified more than once", v->key);
		xfree(v->data);
		v->data_count = 0;
	}

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		char *endptr;
		unsigned long num;

		errno = 0;
		num = strtoul(value, &endptr, 0);
		if ((num == 0 && errno == EINVAL)
		    || (*endptr != '\0')) {
			if (strcasecmp(value, "UNLIMITED") == 0
			    || strcasecmp(value, "INFINITE") == 0) {
				num = (uint16_t)-1;
			} else {
				error("%s value \"%s\" is not a valid number", 
					v->key, value);
				return -1;
			}
		} else if (errno == ERANGE) {
			error("%s value (%s) is out of range", v->key, value);
			return -1;
		} else if (num < 0) {
			error("%s value (%s) is less than zero", v->key, value);
			return -1;
		} else if (num > 0xffff) {
			error("%s value (%s) is greater than 65535", v->key, value);
			return -1;
		}
		v->data = xmalloc(sizeof(uint16_t));
		*(uint16_t *)v->data = (uint16_t)num;
	}

	v->data_count = 1;
	return 1;
}

static int _handle_uint32(s_p_values_t *v,
			  const char *value, const char *line, char **leftover)
{
	if (v->data_count != 0) {
		debug("%s specified more than once", v->key);
		xfree(v->data);
		v->data_count = 0;
	}

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		char *endptr;
		unsigned long num;

		errno = 0;
		num = strtoul(value, &endptr, 0);
		if ((num == 0 && errno == EINVAL)
		    || (*endptr != '\0')) {
			if (strcasecmp(value, "UNLIMITED") == 0
			    || strcasecmp(value, "INFINITE") == 0) {
				num = (uint32_t)-1;
			} else {
				error("%s value (%s) is not a valid number", 
					v->key, value);
				return -1;
			}
		} else if (errno == ERANGE) {
			error("%s value (%s) is out of range", v->key, value);
			return -1;
		} else if (num < 0) {
			error("%s value (%s) is less than zero", v->key, value);
			return -1;
		} else if (num > 0xffffffff) {
			error("%s value (%s) is greater than 4294967295", 
				v->key, value);
			return -1;
		}
		v->data = xmalloc(sizeof(uint32_t));
		*(uint32_t *)v->data = (uint32_t)num;
	}

	v->data_count = 1;
	return 1;
}

static int _handle_pointer(s_p_values_t *v,
			   const char *value, const char *line, char **leftover)
{
	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		if (v->data_count != 0) {
			debug("%s specified more than once", v->key);
			xfree(v->data);
			v->data_count = 0;
		}
		v->data = xstrdup(value);
	}

	v->data_count = 1;
	return 1;
}

static int _handle_array(s_p_values_t *v,
			 const char *value, const char *line, char **leftover)
{
	void *new_ptr;
	void **data;

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&new_ptr, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		new_ptr = xstrdup(value);
	}
	v->data_count += 1;
	v->data = xrealloc(v->data, (v->data_count)*sizeof(void *));
	data = &((void**)v->data)[v->data_count-1];
	*data = new_ptr;

	return 1;
}

static int _handle_boolean(s_p_values_t *v,
			   const char *value, const char *line, char **leftover)
{
	if (v->data_count != 0) {
		debug("%s specified more than once", v->key);
		xfree(v->data);
		v->data_count = 0;
	}

	if (v->handler != NULL) {
		/* call the handler function */
		int rc;
		rc = v->handler(&v->data, v->type, v->key, value,
				line, leftover);
		if (rc != 1)
			return rc == 0 ? 0 : -1;
	} else {
		bool flag;

		if (!strcasecmp(value, "yes")
		    || !strcasecmp(value, "up")
		    || !strcasecmp(value, "1")) {
			flag = true;
		} else if (!strcasecmp(value, "no")
			   || !strcasecmp(value, "down")
			   || !strcasecmp(value, "0")) {
			flag = false;
		} else {
			error("\"%s\" is not a valid option for \"%s\"",
			      value, v->key);
			return -1;
		}

		v->data = xmalloc(sizeof(bool));
		*(bool *)v->data = flag;
	}

	v->data_count = 1;
	return 1;
}


/*
 * IN line: the entire line that currently being parsed
 * IN/OUT leftover: leftover is a pointer into the "line" string.
 *                  The incoming leftover point is a pointer to the
 *                  character just after the already parsed key/value pair.
 *                  If the handler for that key parses more of the line,
 *                  it will move the leftover pointer to point to the character
 *                  after it has finished parsing in the line.
 */
static void _handle_keyvalue_match(s_p_values_t *v,
				   const char *value, const char *line,
				   char **leftover)
{
/* 	debug3("key = %s, value = %s, line = \"%s\"", */
/* 	       v->key, value, line); */
	switch (v->type) {
	case S_P_IGNORE:
		/* do nothing */
		break;
	case S_P_STRING:
		_handle_string(v, value, line, leftover);
		break;
	case S_P_LONG:
		_handle_long(v, value, line, leftover);
		break;
	case S_P_UINT16:
		_handle_uint16(v, value, line, leftover);
		break;
	case S_P_UINT32:
		_handle_uint32(v, value, line, leftover);
		break;
	case S_P_POINTER:
		_handle_pointer(v, value, line, leftover);
		break;
	case S_P_ARRAY:
		_handle_array(v, value, line, leftover);
		break;
	case S_P_BOOLEAN:
		_handle_boolean(v, value, line, leftover);
		break;
	}
}

/*
 * Return 1 if all characters in "line" are white-space characters,
 *   otherwise return 0.
 */
static int _line_is_space(const char *line)
{
	int len;
	int i;

	if (line == NULL) {
		return 1;
	}
	len = strlen(line);
	for (i = 0; i < len; i++) {
		if (!isspace(line[i]))
			return 0;
	}

	return 1;
}


/*
 * Returns 1 if the line is parsed cleanly, and 0 otherwise.
 */
int s_p_parse_line(s_p_hashtbl_t *hashtbl, const char *line, char **leftover)
{
	char *key, *value;
	char *ptr = (char *)line;
	s_p_values_t *p;
	char *new_leftover;

	_keyvalue_regex_init();

	while (_keyvalue_regex(ptr, &key, &value, &new_leftover) == 0) {
		if ((p = _conf_hashtbl_lookup(hashtbl, key))) {
			_handle_keyvalue_match(p, value,
					       new_leftover, &new_leftover);
			*leftover = ptr = new_leftover;
		} else {
			error("Parsing error at unrecognized key: %s", key);
			xfree(key);
			xfree(value);
			return 0;
		}
		xfree(key);
		xfree(value);
	}

	return 1;
}

/*
 * Returns 1 if the line is parsed cleanly, and 0 otherwise.
 */
static int _parse_next_key(s_p_hashtbl_t *hashtbl,
			   const char *line, char **leftover)
{
	char *key, *value;
	s_p_values_t *p;
	char *new_leftover;

	_keyvalue_regex_init();

	if (_keyvalue_regex(line, &key, &value, &new_leftover) == 0) {
		if ((p = _conf_hashtbl_lookup(hashtbl, key))) {
			_handle_keyvalue_match(p, value,
					       new_leftover, &new_leftover);
			*leftover = new_leftover;
		} else {
			error("Parsing error at unrecognized key: %s", key);
			xfree(key);
			xfree(value);
			*leftover = (char *)line;
			return 0;
		}
		xfree(key);
		xfree(value);
	} else {
		*leftover = (char *)line;
	}

	return 1;
}

/*
 * Returns 1 if the line contained an include directive and the included
 * file was parsed without error.  Returns -1 if the line was an include
 * directive but the included file contained errors.  Returns 0 if
 * no include directive is found.
 */
static int _parse_include_directive(s_p_hashtbl_t *hashtbl,
				    const char *line, char **leftover)
{
	char *ptr;
	char *fn_start, *fn_stop;
	char *filename;

	*leftover = NULL;
	if (strncasecmp("include", line, strlen("include")) == 0) {
		ptr = (char *)line + strlen("include");
		if (!isspace(*ptr))
			return 0;
		while (isspace(*ptr))
			ptr++;
		fn_start = ptr;
		while (!isspace(*ptr))
			ptr++;
		fn_stop = *leftover = ptr;
		filename = xstrndup(fn_start, fn_stop-fn_start);
		if (s_p_parse_file(hashtbl, filename) == SLURM_SUCCESS) {
			xfree(filename);
			return 1;
		} else {
			xfree(filename);
			return -1;
		}
	} else {
		return 0;
	}
}

int s_p_parse_file(s_p_hashtbl_t *hashtbl, char *filename)
{
	FILE *f;
	char line[BUFFER_SIZE];
	char *leftover = NULL;
	int rc = SLURM_SUCCESS;
	int line_number;
	int merged_lines;
	int inc_rc;

	if(!filename) {
		error("s_p_parse_file: No filename given.");
		return SLURM_ERROR;
	}
	
	_keyvalue_regex_init();
	
	f = fopen(filename, "r");
	if (f == NULL) {
		error("s_p_parse_file: unable to read \"%s\": %m",
		      filename);
		return SLURM_ERROR;
	}

	line_number = 1;
	while((merged_lines = _get_next_line(line, BUFFER_SIZE, f)) > 0) {
		/* skip empty lines */
		if (line[0] == '\0') {
			line_number += merged_lines;
			continue;
		}

		inc_rc = _parse_include_directive(hashtbl, line, &leftover);
		if (inc_rc == 0) {
			_parse_next_key(hashtbl, line, &leftover);
		} else if (inc_rc < 0) {
			error("\"Include\" failed in file %s line %d",
			      filename, line_number);
			rc = SLURM_ERROR;
			line_number += merged_lines;
			continue;
		}

		/* Make sure that after parsing only whitespace is left over */
		if (!_line_is_space(leftover)) {
			char *ptr = xstrdup(leftover);
			_strip_cr_nl(ptr);
			error("Parse error in file %s line %d: \"%s\"",
			      filename, line_number, ptr);
			xfree(ptr);
			rc = SLURM_ERROR;
		}
		line_number += merged_lines;
	}

	fclose(f);
	return rc;
}

/*
 * s_p_get_string
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * string.  If the key is found and has a set value, the
 * value is retuned in "str".
 *
 * OUT str - pointer to a copy of the string value
 *           (caller is resonsible for freeing str with xfree())
 * IN key - hash table key.
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "str"
 *   was successfully set, otherwise returns 0;
 *
 * NOTE: Caller is responsible for freeing the returned string with xfree!
 */
int s_p_get_string(char **str, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_STRING) {
		error("Key \"%s\" is not a string\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*str = xstrdup((char *)p->data);

	return 1;
}

/*
 * s_p_get_long
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * long.  If the key is found and has a set value, the
 * value is retuned in "num".
 *
 * OUT num - pointer to a long where the value is returned
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "num"
 *   was successfully set, otherwise returns 0;
 */
int s_p_get_long(long *num, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_LONG) {
		error("Key \"%s\" is not a long\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*num = *(long *)p->data;

	return 1;
}

/*
 * s_p_get_uint16
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * uint16.  If the key is found and has a set value, the
 * value is retuned in "num".
 *
 * OUT num - pointer to a uint16_t where the value is returned
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "num"
 *   was successfully set, otherwise returns 0;
 */
int s_p_get_uint16(uint16_t *num, const char *key,
		   const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_UINT16) {
		error("Key \"%s\" is not a uint16_t\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*num = *(uint16_t *)p->data;

	return 1;
}

/*
 * s_p_get_uint32
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * uint32.  If the key is found and has a set value, the
 * value is retuned in "num".
 *
 * OUT num - pointer to a uint32_t where the value is returned
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "num"
 *   was successfully set, otherwise returns 0;
 */
int s_p_get_uint32(uint32_t *num, const char *key,
		   const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_UINT32) {
		error("Key \"%s\" is not a uint32_t\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*num = *(uint32_t *)p->data;

	return 1;
}

/*
 * s_p_get_pointer
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * pointer.  If the key is found and has a set value, the
 * value is retuned in "ptr".
 *
 * OUT ptr - pointer to a void pointer where the value is returned
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "ptr"
 *   was successfully set, otherwise returns 0;
 */
int s_p_get_pointer(void **ptr, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_POINTER) {
		error("Key \"%s\" is not a pointer\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*ptr = p->data;

	return 1;
}


/*
 * s_p_get_array
 *
 * Most s_p_ data types allow a key to appear only once in a file
 * (s_p_parse_file) or line (s_p_parse_line).  S_P_ARRAY is the exception.
 *
 * S_P_ARRAY allows a key to appear any number of times.  Each time
 * a particular key is found the value array grows by one element, and
 * that element contains a pointer to the newly parsed value.  You can
 * think of this as being an array of S_P_POINTER types.
 *
 * OUT ptr_array - pointer to a void pointer-pointer where the value is returned
 * OUT count - length of ptr_array
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and both
 *   "ptr_array" and "count" were successfully set, otherwise returns 0.
 */
int s_p_get_array(void **ptr_array[], int *count, 
		  const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_ARRAY) {
		error("Key \"%s\" is not an array\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*ptr_array = (void **)p->data;
	*count = p->data_count;

	return 1;
}

/*
 * s_p_get_boolean
 *
 * Search for a key in a s_p_hashtbl_t with value of type
 * boolean.  If the key is found and has a set value, the
 * value is retuned in "flag".
 *
 * OUT flag - pointer to a bool where the value is returned
 * IN key - hash table key
 * IN hashtbl - hash table created by s_p_hashtbl_create()
 *
 * Returns 1 when a value was set for "key" during parsing and "num"
 *   was successfully set, otherwise returns 0;
 */
int s_p_get_boolean(bool *flag, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p;

	if (!hashtbl)
		return 0;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return 0;
	}
	if (p->type != S_P_BOOLEAN) {
		error("Key \"%s\" is not a boolean\n", key);
		return 0;
	}
	if (p->data_count == 0) {
		return 0;
	}

	*flag = *(bool *)p->data;

	return 1;
}


/*
 * Given an "options" array, print the current values of all
 * options in supplied hash table "hashtbl".
 *
 * Primarily for debugging purposes.
 */
void s_p_dump_values(const s_p_hashtbl_t *hashtbl,
		     const s_p_options_t options[])
{
	const s_p_options_t *op = NULL;
	long num;
	uint16_t num16;
	uint32_t num32;
	char *str;
	void *ptr;
	void **ptr_array;
	int count;
	bool flag;

	for (op = options; op->key != NULL; op++) {
		switch(op->type) {
		case S_P_STRING:
			if (s_p_get_string(&str, op->key, hashtbl)) {
			        verbose("%s = %s", op->key, str);
				xfree(str);
			} else {
				verbose("%s", op->key);
			}
			break;
		case S_P_LONG:
			if (s_p_get_long(&num, op->key, hashtbl))
				verbose("%s = %ld", op->key, num);
			else
				verbose("%s", op->key);
			break;
		case S_P_UINT16:
			if (s_p_get_uint16(&num16, op->key, hashtbl))
				verbose("%s = %hu", op->key, num16);
			else
				verbose("%s", op->key);
			break;
		case S_P_UINT32:
			if (s_p_get_uint32(&num32, op->key, hashtbl))
				verbose("%s = %u", op->key, num32);
			else
				verbose("%s", op->key);
			break;
		case S_P_POINTER:
			if (s_p_get_pointer(&ptr, op->key, hashtbl))
				verbose("%s = %x", op->key, ptr);
			else
				verbose("%s", op->key);
			break;
		case S_P_ARRAY:
			if (s_p_get_array(&ptr_array, &count,
					  op->key, hashtbl)) {
				verbose("%s, count = %d", op->key, count);
			} else {
				verbose("%s", op->key);
			}
			break;
		case S_P_BOOLEAN:
			if (s_p_get_boolean(&flag, op->key, hashtbl)) {
				verbose("%s = %s", op->key,
					flag ? "TRUE" : "FALSE");
			} else {
				verbose("%s", op->key);
			}
			break;
		case S_P_IGNORE:
			break;
		}
	}
}
