/*****************************************************************************\
 *  parse_config.c - parse any slurm.conf-like configuration file
 *
 *  NOTE: when you see the prefix "s_p_", think "slurm parser".
 *****************************************************************************
 *  Copyright (C) 2006-2007 The Regents of the University of California.
 *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Christopher J. Morrone <morrone2@llnl.gov>.
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  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.
\*****************************************************************************/

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

#include "src/common/fetch_config.h"
#include "src/common/hostlist.h"
#include "src/common/log.h"
#include "src/common/macros.h"
#include "src/common/pack.h"
#include "src/common/parse_config.h"
#include "src/common/parse_value.h"
#include "src/common/read_config.h"
#include "src/common/run_in_daemon.h"
#include "src/common/slurm_protocol_defs.h"
#include "src/common/slurm_protocol_socket.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xregex.h"
#include "src/common/xstring.h"

#include "slurm/slurm.h"

strong_alias(s_p_hashtbl_create,	slurm_s_p_hashtbl_create);
strong_alias(s_p_hashtbl_destroy,	slurm_s_p_hashtbl_destroy);
strong_alias(s_p_parse_buffer,		slurm_s_p_parse_buffer);
strong_alias(s_p_parse_file,		slurm_s_p_parse_file);
strong_alias(s_p_parse_pair,		slurm_s_p_parse_pair);
strong_alias(s_p_parse_line,		slurm_s_p_parse_line);
strong_alias(s_p_hashtbl_merge, 	slurm_s_p_hashtbl_merge);
strong_alias(s_p_get_string,		slurm_s_p_get_string);
strong_alias(s_p_get_long,		slurm_s_p_get_long);
strong_alias(s_p_get_uint16,		slurm_s_p_get_uint16);
strong_alias(s_p_get_uint32,		slurm_s_p_get_uint32);
strong_alias(s_p_get_uint64,		slurm_s_p_get_uint64);
strong_alias(s_p_get_float,		slurm_s_p_get_float);
strong_alias(s_p_get_double,		slurm_s_p_get_double);
strong_alias(s_p_get_long_double,	slurm_s_p_get_long_double);
strong_alias(s_p_get_pointer,		slurm_s_p_get_pointer);
strong_alias(s_p_get_array,		slurm_s_p_get_array);
strong_alias(s_p_get_boolean,		slurm_s_p_get_boolean);
strong_alias(s_p_dump_values,		slurm_s_p_dump_values);
strong_alias(transfer_s_p_options,	slurm_transfer_s_p_options);

#define CONF_HASH_LEN 173

static char *keyvalue_pattern =
	"^[[:space:]]*"
	"([[:alnum:]_.]+)" /* key */
	"[[:space:]]*([-*+/]?)=[[:space:]]*"
	"((\"([^\"]*)\")|([^[:space:]]+))" /* value: quoted with whitespace,
					    * or unquoted and no whitespace */
	"([[:space:]]|$)";

struct s_p_values {
	char *key;
	int type;
	slurm_parser_operator_t operator;
	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;
};

struct s_p_hashtbl {
	regex_t keyvalue_re;
	s_p_values_t *hash[CONF_HASH_LEN];
};

typedef struct _expline_values_st {
	s_p_hashtbl_t*	template;
	s_p_hashtbl_t*	index;
	s_p_hashtbl_t**	values;
} _expline_values_t;

list_t *conf_includes_list = NULL;

/*
 * NOTE - "key" is case insensitive.
 */
static int _conf_hashtbl_index(const char *key)
{
	unsigned int hashval;

	xassert(key);
	for (hashval = 0; *key != 0; key++)
		hashval = tolower(*key) + 31 * hashval;
	return hashval % CONF_HASH_LEN;
}

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

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

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

	xassert(key);
	if (!tbl)
		return NULL;

	idx = _conf_hashtbl_index(key);
	for (p = tbl->hash[idx]; p; p = p->next) {
		if (xstrcasecmp(p->key, key) == 0)
			return p;
	}

	return NULL;
}

s_p_hashtbl_t *s_p_hashtbl_create_cnt(const s_p_options_t options[], int *cnt)
{
	s_p_hashtbl_t *tbl = xmalloc(sizeof(*tbl));

	if (cnt)
		*cnt = 0;
	for (const s_p_options_t *op = options; op->key; op++) {
		s_p_values_t *value = xmalloc(sizeof(*value));
		if (cnt)
			(*cnt)++;
		value->key = xstrdup(op->key);
		value->operator = S_P_OPERATOR_SET;
		value->type = op->type;
		value->data_count = 0;
		value->data = NULL;
		value->next = NULL;
		value->handler = op->handler;
		value->destroy = op->destroy;
		if (op->type == S_P_LINE || op->type == S_P_EXPLINE) {
			/* line_options mandatory for S_P_*LINE */
			_expline_values_t *expdata = xmalloc(sizeof(*expdata));
			xassert(op->line_options);
			expdata->template =
				s_p_hashtbl_create(op->line_options);
			expdata->index = xmalloc(sizeof(*expdata->index));
			expdata->values = NULL;
			value->data = expdata;
		}
		_conf_hashtbl_insert(tbl, value);
	}

	if (regcomp(&tbl->keyvalue_re, keyvalue_pattern, REG_EXTENDED))
		fatal("keyvalue regex compilation failed");

	return tbl;
}

extern s_p_hashtbl_t *s_p_hashtbl_create(const s_p_options_t options[])
{
	return s_p_hashtbl_create_cnt(options, NULL);
}

/* Swap the data in two data structures without changing the linked list
 * pointers */
static void _conf_hashtbl_swap_data(s_p_values_t *data_1,
				    s_p_values_t *data_2)
{
	s_p_values_t *next_1, *next_2;
	s_p_values_t tmp_values;

	next_1 = data_1->next;
	next_2 = data_2->next;

	memcpy(&tmp_values, data_1, sizeof(s_p_values_t));
	memcpy(data_1, data_2, sizeof(s_p_values_t));
	memcpy(data_2, &tmp_values, sizeof(s_p_values_t));

	data_1->next = next_1;
	data_2->next = next_2;
}

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

	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;
		case S_P_LINE:
		case S_P_EXPLINE:
			v = (_expline_values_t*)p->data;
			s_p_hashtbl_destroy(v->template);
			s_p_hashtbl_destroy(v->index);
			for (i = 0; i < p->data_count; ++i) {
				s_p_hashtbl_destroy(v->values[i]);
			}
			xfree(v->values);
			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 *tbl)
{
	s_p_values_t *p, *next;

	if (!tbl)
		return;

	for (int i = 0; i < CONF_HASH_LEN; i++) {
		for (p = tbl->hash[i]; p; p = next) {
			next = p->next;
			_conf_file_values_free(p);
		}
	}

	regfree(&tbl->keyvalue_re);

	xfree(tbl);
}

/*
 * IN tbl - table to work off
 * 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(s_p_hashtbl_t *tbl, const char *line,
			   char **key, char **value, char **remaining,
			   slurm_parser_operator_t *operator)
{
	size_t nmatch = 8;
	regmatch_t pmatch[8];
	char op;
	int rc;

	*key = NULL;
	*value = NULL;
	*remaining = (char *)line;
	*operator = S_P_OPERATOR_SET;
	memset(pmatch, 0, sizeof(regmatch_t)*nmatch);

	if ((rc = regexec(&tbl->keyvalue_re, line, nmatch, pmatch, 0))) {
		if (rc != REG_NOMATCH)
			dump_regex_error(rc, &tbl->keyvalue_re, "regexec(%s)",
					 line);
		return -1;
	}

	*key = (char *)(xstrndup(line + pmatch[1].rm_so,
				 pmatch[1].rm_eo - pmatch[1].rm_so));
	if (pmatch[2].rm_so != -1 &&
	    (pmatch[2].rm_so != pmatch[2].rm_eo)) {
		op = *(line + pmatch[2].rm_so);
		if (op == '+') {
			*operator = S_P_OPERATOR_ADD;
		} else if (op == '-') {
			*operator = S_P_OPERATOR_SUB;
		} else if (op == '*') {
			*operator = S_P_OPERATOR_MUL;
		} else if (op == '/') {
			*operator = S_P_OPERATOR_DIV;
		}
	}
	if (pmatch[5].rm_so != -1) {
		*value = (char *)(xstrndup(line + pmatch[5].rm_so,
					   pmatch[5].rm_eo - pmatch[5].rm_so));
	} else if (pmatch[6].rm_so != -1) {
		*value = (char *)(xstrndup(line + pmatch[6].rm_so,
					   pmatch[6].rm_eo - pmatch[6].rm_so));
	} else {
		*value = xstrdup("");
	}

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

	return 0;
}

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

	if (len == 0)
		return len;	/* Empty line */

	for (ptr = buf+len-1; ptr >= buf; ptr--) {
		if (*ptr == '\\')
			bs++;
		else if (isspace((int)*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];
	}
}

/* This can be used to make sure files are the same across nodes if needed */
static void _compute_hash_val(uint32_t *hash_val, char *line)
{
	int idx, i, len;

	if (!hash_val)
		return;

	len = strlen(line);
	for (i = 0; i < len; i++) {
		(*hash_val) = ( (*hash_val) ^ line[i] << 8 );

		for (idx = 0; idx < 8; ++idx) {
			if ((*hash_val) & 0x8000) {
				(*hash_val) <<= 1;
				(*hash_val) = (*hash_val) ^ 4129;
			} else
				(*hash_val) <<= 1;
		}
	}
}


/*
 * Reads the next line from the "file" into buffer "buf".
 *
 * Concatenates 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,
			  uint32_t *hash_val, FILE *file)
{
	char *ptr = buf;
	int leftover = buf_size;
	int read_size, new_size;
	int lines = 0;

	while (fgets(ptr, leftover, file)) {
		lines++;
		_compute_hash_val(hash_val, ptr);
		_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;
}

/*
 * Copy all the keys from 'from_hashtbl' along with their types, handler, and
 * destroy fields. Omit values in the copy and initialize them to NULL/0.
 */
s_p_hashtbl_t *_hashtbl_copy_keys(const s_p_hashtbl_t *from_tbl)
{
	s_p_hashtbl_t *to_tbl = xmalloc(sizeof(*to_tbl));

	xassert(from_tbl);

	for (int i = 0; i < CONF_HASH_LEN; ++i) {
		for (s_p_values_t *val_ptr = from_tbl->hash[i];
		     val_ptr; val_ptr = val_ptr->next) {
			s_p_values_t *val_copy = xmalloc(sizeof(*val_copy));

			val_copy->key = xstrdup(val_ptr->key);
			val_copy->operator = val_ptr->operator;
			val_copy->type = val_ptr->type;
			val_copy->handler = val_ptr->handler;
			val_copy->destroy = val_ptr->destroy;
			_conf_hashtbl_insert(to_tbl, val_copy);
		}
	}

	/*
	 * We cannot copy a regex since a regfree() on either
	 * the original or the copy can affect the other one.
	 */
	if (regcomp(&to_tbl->keyvalue_re, keyvalue_pattern, REG_EXTENDED))
		fatal("keyvalue regex compilation failed");

	return to_tbl;
}


static int _handle_common(s_p_values_t *v,
			  const char *value, const char *line, char **leftover,
			  void* (*convert)(const char* key, const char* value))
{
	if (v->data_count != 0) {
		error_in_daemon("%s 1 specified more than once, latest value used",
				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 = convert(v->key, value);
		if (!v->data) {
			return -1;
		}
	}

	v->data_count = 1;
	return 1;
}

static void *_handle_string(const char *key, const char *value)
{
	return xstrdup(value);
}

static void *_handle_long(const char *key, const char *value)
{
	long *data = xmalloc(sizeof(*data));
	if (s_p_handle_long(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_uint16(const char *key, const char *value)
{
	uint16_t *data = xmalloc(sizeof(*data));
	if (s_p_handle_uint16(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_uint32(const char *key, const char *value)
{
	uint32_t *data = xmalloc(sizeof(*data));
	if (s_p_handle_uint32(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_uint64(const char *key, const char *value)
{
	uint64_t *data = xmalloc(sizeof(*data));
	if (s_p_handle_uint64(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_boolean(const char *key, const char *value)
{
	bool *data = xmalloc(sizeof(*data));
	if (s_p_handle_boolean(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_float(const char *key, const char *value)
{
	float *data = xmalloc(sizeof(*data));
	if (s_p_handle_float(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_double(const char *key, const char *value)
{
	double *data = xmalloc(sizeof(*data));
	if (s_p_handle_double(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

static void *_handle_ldouble(const char *key, const char *value)
{
	long double *data = xmalloc(sizeof(*data));
	if (s_p_handle_long_double(data, key, value) == SLURM_ERROR) {
		xfree(data);
		return NULL;
	}
	return data;
}

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) {
			error_in_daemon("%s 2 specified more than once, latest value used",
					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;
}

/* custom destroyer that just do nothing, sub-hashtable freeing is performed
 * in _conf_file_values_free for S_P_LINE and S_P_EXPLINE */
static void _empty_destroy(void* data) { }

/* sc = string case
 * look for an already indexed table with the same (master) key.
 * if a table is found, merge the new one within.
 * otherwise, add the new table and create an index for further lookup.
 */
static void _handle_expline_sc(s_p_hashtbl_t* index_tbl,
			       const char* master_value,
			       s_p_hashtbl_t* tbl,
			       s_p_hashtbl_t*** tables,
			       int* tables_count)
{
	s_p_values_t* matchp_index,* index_value;
	matchp_index = _conf_hashtbl_lookup(index_tbl, master_value);
	if (matchp_index) {
		s_p_hashtbl_merge_override(
			(s_p_hashtbl_t*)matchp_index->data, tbl);
		s_p_hashtbl_destroy(tbl);
	} else {
		index_value = xmalloc(sizeof(s_p_values_t));
		index_value->key = xstrdup(master_value);
		index_value->destroy = _empty_destroy;
		index_value->data = tbl;
		_conf_hashtbl_insert(index_tbl, index_value);
		(*tables_count) += 1;
		(*tables) = (s_p_hashtbl_t**)xrealloc(*tables,
				*tables_count * sizeof(s_p_hashtbl_t*));
		(*tables)[*tables_count - 1] = tbl;
	}
}

static int _handle_expline_cmp_long(const void* v1, const void* v2)
{
	return *((long*)v1) != *((long*)v2);
}
static int _handle_expline_cmp_uint16(const void* v1, const void* v2)
{
	return *((uint16_t*)v1) != *((uint16_t*)v2);
}
static int _handle_expline_cmp_uint32(const void* v1, const void* v2)
{
	return *((uint32_t*)v1) != *((uint32_t*)v2);
}
static int _handle_expline_cmp_uint64(const void* v1, const void* v2)
{
	return *((uint64_t*)v1) != *((uint64_t*)v2);
}
static int _handle_expline_cmp_float(const void* v1, const void* v2)
{
	return *((float*)v1) != *((float*)v2);
}
static int _handle_expline_cmp_double(const void* v1, const void* v2)
{
	return *((double*)v1) != *((double*)v2);
}
static int _handle_expline_cmp_ldouble(const void* v1, const void* v2)
{
	return *((long double*)v1) != *((long double*)v2);
}

/* ac = array case
 * the master key type is not string. Iterate over the tables looking
 * for the value associated with the new master to add/update.
 * If a corresponding table is found, update it with the content of the
 * new one, otherwise, add the new table.
 */
static void _handle_expline_ac(s_p_hashtbl_t* tbl,
			       const char* master_key,
			       const void* master_value,
			       int (*cmp)(const void* v1, const void* v2),
			       s_p_hashtbl_t*** tables,
			       int* tables_count)
{
	s_p_values_t* matchp;
	s_p_hashtbl_t* table;
	int i;

	for (i = 0; i < *tables_count; ++i) {
		table = (*tables)[i];
		matchp = _conf_hashtbl_lookup(table, master_key);
		xassert(matchp); /* same template, should never be NULL */
		if (!cmp(matchp->data, master_value)) {
			/* found hash tbl to merge with */
			s_p_hashtbl_merge_override(table, tbl);
			s_p_hashtbl_destroy(tbl);
			return;
		}
	}

	/* not found, just add it */
	*tables_count += 1;
	*tables = (s_p_hashtbl_t**)xrealloc(*tables,
			*tables_count * sizeof(s_p_hashtbl_t*));
	*tables[*tables_count - 1] = tbl;
}

/*
 * merge a freshly generated s_p_hashtbl_t from the line/expline processing
 * with the already added s_p_hashtbl_t elements of the previously processed
 * siblings
 */
static void _handle_expline_merge(_expline_values_t* v_data,
				  int* tables_count, /* not accessible in v_data
							since in v */
				  const char* master_key,
				  s_p_hashtbl_t* current_tbl)
{
	s_p_values_t* matchp = _conf_hashtbl_lookup(current_tbl, master_key);

	/* record should have been skipped if key not in sub-hash-table */
	xassert(matchp);

	switch(matchp->type) {
	case S_P_STRING:
		_handle_expline_sc(v_data->index, matchp->data, current_tbl,
				   &v_data->values, tables_count);
		break;
	case S_P_LONG:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_long, &v_data->values,
				   tables_count);
		break;
	case S_P_UINT16:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_uint16, &v_data->values,
				   tables_count);
		break;
	case S_P_UINT32:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_uint32, &v_data->values,
				   tables_count);
		break;
	case S_P_UINT64:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_uint64, &v_data->values,
				   tables_count);
		break;
	case S_P_FLOAT:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_float, &v_data->values,
				   tables_count);
		break;
	case S_P_DOUBLE:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_double, &v_data->values,
				   tables_count);
		break;
	case S_P_LONG_DOUBLE:
		_handle_expline_ac(current_tbl, master_key, matchp->data,
				   _handle_expline_cmp_ldouble, &v_data->values,
				   tables_count);
		break;
	}
}

static int _handle_line(s_p_values_t* v, const char* value,
			const char* line, char** leftover)
{
	_expline_values_t* v_data = (_expline_values_t*)v->data;
	s_p_hashtbl_t* newtable;

	newtable = _hashtbl_copy_keys(v_data->template);
	if (s_p_parse_line_complete(newtable, v->key, value, line,
				    leftover) == SLURM_ERROR) {
		s_p_hashtbl_destroy(newtable);
		return -1;
	}

	_handle_expline_merge(v_data, &v->data_count, v->key, newtable);

	return 1;
}


static int _handle_expline(s_p_values_t* v, const char* value,
			   const char* line, char** leftover)
{
	_expline_values_t* v_data = (_expline_values_t*)v->data;
	s_p_hashtbl_t** new_tables;
	int new_tables_count, i;

	if (s_p_parse_line_expanded(v_data->template,
				    &new_tables, &new_tables_count,
				    v->key, value,
				    line, leftover) == SLURM_ERROR) {
		return -1;
	}

	for (i = 0; i < new_tables_count; ++i) {
		_handle_expline_merge(v_data, &v->data_count,
				      v->key, new_tables[i]);
	}
	xfree(new_tables);
	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.
 * RET:
 *	-1 if the value is invalid.
 *	0 if the value is validbut no value will be set for "data".
 *	1 if "data" is set.
 */
static int _handle_keyvalue_match(s_p_values_t *v,
				  const char *value, const char *line,
				  char **leftover)
{
	int rc = 1;

	switch (v->type) {
	case S_P_IGNORE:
		/* do nothing */
		break;
	case S_P_STRING:
		rc = _handle_common(v, value, line, leftover, _handle_string);
		break;
	case S_P_LONG:
		rc = _handle_common(v, value, line, leftover, _handle_long);
		break;
	case S_P_UINT16:
		rc = _handle_common(v, value, line, leftover, _handle_uint16);
		break;
	case S_P_UINT32:
		rc = _handle_common(v, value, line, leftover, _handle_uint32);
		break;
	case S_P_UINT64:
		rc = _handle_common(v, value, line, leftover, _handle_uint64);
		break;
	case S_P_POINTER:
		rc = _handle_pointer(v, value, line, leftover);
		break;
	case S_P_ARRAY:
		rc = _handle_array(v, value, line, leftover);
		break;
	case S_P_BOOLEAN:
		rc = _handle_common(v, value, line, leftover, _handle_boolean);
		break;
	case S_P_LINE:
		rc = _handle_line(v, value, line, leftover);
		break;
	case S_P_EXPLINE:
		rc = _handle_expline(v, value, line, leftover);
		break;
	case S_P_FLOAT:
		rc = _handle_common(v, value, line, leftover, _handle_float);
		break;
	case S_P_DOUBLE:
		rc = _handle_common(v, value, line, leftover, _handle_double);
		break;
	case S_P_LONG_DOUBLE:
		rc = _handle_common(v, value, line, leftover, _handle_ldouble);
		break;
	default:
		fatal("%s: unsupported s_p_value_t type %d", __func__, v->type);
	}
	return rc;
}

/*
 * 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((int)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;
	slurm_parser_operator_t op;

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

	return 1;
}

/*
 * Returns 1 if the line is parsed cleanly, and 0 otherwise.
 * IN ingore_new - if set do not treat unrecognized input as a fatal error
 */
static int _parse_next_key(s_p_hashtbl_t *hashtbl,
			   const char *line, char **leftover, bool ignore_new)
{
	char *key, *value;
	s_p_values_t *p;
	char *new_leftover;
	slurm_parser_operator_t op;

	if (_keyvalue_regex(hashtbl, line, &key, &value, &new_leftover, &op) == 0) {
		if ((p = _conf_hashtbl_lookup(hashtbl, key))) {
			p->operator = op;
			if (_handle_keyvalue_match(p, value, new_leftover,
						   &new_leftover) == -1) {
				xfree(key);
				xfree(value);
				*leftover = (char *)line;
				errno = EINVAL;
				return 0;
			}
			*leftover = new_leftover;
		} else if (ignore_new) {
			debug("%s: Parsing error at unrecognized key: %s",
			      __func__, key);
			*leftover = (char *)line;
		} else {
			error("%s: Parsing error at unrecognized key: %s",
			      __func__, key);
			xfree(key);
			xfree(value);
			*leftover = (char *)line;
			errno = EINVAL;
			return 0;
		}
		xfree(key);
		xfree(value);
	} else {
		*leftover = (char *)line;
	}

	return 1;
}

static char *_parse_for_format(s_p_hashtbl_t *f_hashtbl, char *path)
{
	char *filename = xstrdup(path);
	char *format = NULL;
	char *tmp_str = NULL;

	while (1) {
		if ((format = strstr(filename, "%c"))) { /* ClusterName */
			if (!s_p_get_string(&tmp_str, "ClusterName",f_hashtbl)){
				error("%s: Did not get ClusterName for include "
				      "path", __func__);
				xfree(filename);
				break;
			}
			xstrtolower(tmp_str);
		} else {	/* No special characters */
			break;
		}

		/* Build the new path if tmp_str is not NULL*/
		if (tmp_str) {
			format[0] = '\0';
			xstrfmtcat(filename, "%s%s", tmp_str, format+2);
			xfree(tmp_str);
		} else {
			error("%s: Value for include modifier %s could "
			      "not be found", __func__, format);
			xfree(filename);
			break;
		}
	}

	return filename;
}

/*
 * ListDelF for conf_includes_list
 *
 * IN/OUT: object (conf_includes_map_t *map)
 */
static void _delete_conf_includes(void *object)
{
	conf_includes_map_t *map = object;

	if (map) {
		xfree(map->conf_file);
		FREE_NULL_LIST(map->include_list);
		xfree(map);
	}
}

/*
 * Allocate memory for conf_includes_list if needed.
 *
 * Append the include_file to its appropriate conf_file mapping if found,
 * otherwise create a map for conf_file <-> include_file and append it to
 * conf_includes_list.
 *
 * IN: include_file to be appended.
 * IN: conf_file where include_file belongs to.
 */
static void _handle_include(char *include_file, char *conf_file)
{
	conf_includes_map_t *map = NULL;

	xassert(include_file);
	xassert(conf_file);

	if (!conf_includes_list)
		conf_includes_list = list_create(_delete_conf_includes);

	if (!(map = list_find_first_ro(conf_includes_list,
				       find_map_conf_file,
				       conf_file))) {
		map = xmalloc(sizeof(*map));
		map->conf_file = xstrdup(conf_file);
		map->include_list = list_create(xfree_ptr);
		list_append(map->include_list, xstrdup(include_file));
		list_append(conf_includes_list, map);
	} else if (!list_find_first_ro(map->include_list,
				       slurm_find_char_exact_in_list,
				       include_file)) {
		list_append(map->include_list, xstrdup(include_file));
	}
}

/*
 * 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, uint32_t *hash_val,
				    const char *line, char **leftover,
				    uint32_t flags, char *slurm_conf_path,
				    char *last_ancestor)
{
	char *ptr;
	char *fn_start, *fn_stop;
	char *file_name, *path_name;
	char *file_with_mod;
	int rc;
	struct stat temp;

	*leftover = NULL;
	if (xstrncasecmp("include", line, strlen("include")) == 0) {
		ptr = (char *)line + strlen("include");

		if (!isspace((int)*ptr))
			return 0;
		while (isspace((int)*ptr))
			ptr++;
		fn_start = ptr;
		while (!isspace((int)*ptr))
			ptr++;
		fn_stop = *leftover = ptr;

		file_with_mod = xstrndup(fn_start, fn_stop-fn_start);
		file_name = _parse_for_format(hashtbl, file_with_mod);//
		xfree(file_with_mod);
		if (!file_name)	/* Error printed by _parse_for_format() */
			return -1;
		path_name = get_extra_conf_path(file_name);

		stat(path_name, &temp);
		if ((flags & PARSE_FLAGS_CHECK_PERMISSIONS) &&
		   ((temp.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0600))
			fatal("Included file %s at %s should be 600 is %o accessible for group or others",
			      file_name,
			      path_name,
			      temp.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
		if (!last_ancestor)
			last_ancestor = xbasename(slurm_conf_path);

		if (xstrstr(file_name, "*")) {
			if ((!xstrcasecmp(last_ancestor,"slurm.conf")) ||
			    (!(slurm_conf.debug_flags & DEBUG_FLAG_GLOB_SILENCE))) {
				error("Slurm does not support glob parsing. %s from %s will be skipped over. If this expected, ignore this message and set DebugFlags=GLOB_SILENCE in your slurm.conf.",
				      path_name, last_ancestor);
			}
			xfree(path_name);
			xfree(file_name);
			return -1;
		} else {
			rc = s_p_parse_file(hashtbl, hash_val, path_name, flags,
					    last_ancestor);
		}

		xfree(path_name);
		if (rc == SLURM_SUCCESS) {
			if (!xstrstr(file_name, "/") && running_in_slurmctld())
				_handle_include(file_name, last_ancestor);
			xfree(file_name);
			return 1;
		} else {
			xfree(file_name);
			return -1;
		}
	} else {
		return 0;
	}
}

int s_p_parse_file(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, char *filename,
		   uint32_t flags, char *last_ancestor)
{
	FILE *f;
	char *leftover = NULL;
	int i, rc = SLURM_SUCCESS;
	int line_number;
	int merged_lines;
	int inc_rc;
	struct stat stat_buf;
	char *line = NULL;
	bool ignore_new = (flags & PARSE_FLAGS_IGNORE_NEW);

	if (!filename) {
		error("s_p_parse_file: No filename given.");
		return SLURM_ERROR;
	}

	for (i = 0; ; i++) {
		if (i == 1) {	/* Long once, on first retry */
			error("%s: cannot stat file %s: %m, retrying in 1sec up to 60sec",
			      __func__, filename);
		}
		if (i >= 60)	/* Give up after 60 seconds */
			return SLURM_ERROR;
		if (i > 0)
			sleep(1);
		if (stat(filename, &stat_buf) >= 0)
			break;
	}
	if (stat_buf.st_size == 0) {
		info("s_p_parse_file: file \"%s\" is empty", filename);
		return SLURM_SUCCESS;
	}
	f = fopen(filename, "r");
	if (f == NULL) {
		error("s_p_parse_file: unable to read \"%s\": %m",
		      filename);
		return SLURM_ERROR;
	}

	/* Buffer needs one extra byte for trailing '\0' */
	line = xmalloc(stat_buf.st_size + 1);
	line_number = 1;
	while ((merged_lines = _get_next_line(
			line, stat_buf.st_size + 1, hash_val, f)) > 0) {
		/* skip empty lines */
		if (line[0] == '\0') {
			line_number += merged_lines;
			continue;
		}

		inc_rc = _parse_include_directive(hashtbl, hash_val,
						  line, &leftover, flags,
						  filename, last_ancestor);
		if (inc_rc == 0 && !(flags & PARSE_FLAGS_INCLUDE_ONLY)) {
			if (!_parse_next_key(hashtbl, line, &leftover,
					     ignore_new)) {
				rc = SLURM_ERROR;
				line_number += merged_lines;
				continue;
			}
		} 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);
			if (ignore_new) {
				debug("Parse error in file %s line %d: \"%s\"",
				      filename, line_number, ptr);
			} else {
				error("Parse error in file %s line %d: \"%s\"",
				      filename, line_number, ptr);
				rc = SLURM_ERROR;
			}
			xfree(ptr);
		}
		line_number += merged_lines;
	}

	xfree(line);
	fclose(f);
	return rc;
}

int s_p_parse_buffer(s_p_hashtbl_t *hashtbl, uint32_t *hash_val,
		     buf_t *buffer, bool ignore_new)
{
	char *leftover = NULL;
	int rc = SLURM_SUCCESS;
	int line_number;
	char *tmp_str = NULL;

	if (!buffer) {
		error("s_p_parse_buffer: No buffer given.");
		return SLURM_ERROR;
	}

	line_number = 0;
	while (remaining_buf(buffer) > 0) {
		safe_unpackstr(&tmp_str, buffer);
		if (tmp_str != NULL) {
			line_number++;
			if (*tmp_str == '\0') {
				xfree(tmp_str);
				continue;
			}
			if (!_parse_next_key(hashtbl, tmp_str, &leftover,
					     ignore_new)) {
				rc = SLURM_ERROR;
				xfree(tmp_str);
				continue;
			}
			/* Make sure that after parsing only whitespace
			   is left over */
			if (!_line_is_space(leftover)) {
				char *ptr = xstrdup(leftover);
				_strip_cr_nl(ptr);
				if (ignore_new) {
					debug("s_p_parse_buffer : error in line"
					      " %d: \"%s\"", line_number, ptr);
				} else {
					error("s_p_parse_buffer : error in line"
					      " %d: \"%s\"", line_number, ptr);
					rc = SLURM_ERROR;
				}
				xfree(ptr);
			}
			xfree(tmp_str);
			if (rc == SLURM_SUCCESS)
				continue;
		}
	unpack_error:
		debug3("s_p_parse_buffer: ending after line %u",
		       line_number);
		break;
	}

	return rc;
}

/*
 * s_p_hashtbl_merge
 *
 * Merge the contents of two s_p_hashtbl_t data structures. Anything in
 * from_hashtbl that does not also appear in to_hashtbl is transferred to it.
 * This is intended primary to support multiple lines of DEFAULT configuration
 * information and preserve the default values while adding new defaults.
 *
 * IN from_hashtbl - Source of old data
 * IN to_hashtbl - Destination for old data
 */
void s_p_hashtbl_merge(s_p_hashtbl_t *to_tbl, s_p_hashtbl_t *from_tbl)
{
	int i;
	s_p_values_t **val_pptr, *val_ptr, *match_ptr;

	if (!to_tbl || !from_tbl)
		return;

	for (i = 0; i < CONF_HASH_LEN; i++) {
		val_pptr = &from_tbl->hash[i];
		val_ptr = from_tbl->hash[i];
		while (val_ptr) {
			if (val_ptr->data_count == 0) {
				/* No data in from_tbl record to move.
				 * Skip record */
				val_pptr = &val_ptr->next;
				val_ptr = val_ptr->next;
				continue;
			}
			match_ptr = _conf_hashtbl_lookup(to_tbl, val_ptr->key);
			if (match_ptr) {	/* Found matching key */
				if (match_ptr->data_count == 0) {
					_conf_hashtbl_swap_data(val_ptr,
								match_ptr);
				}
				val_pptr = &val_ptr->next;
				val_ptr = val_ptr->next;
			} else {	/* No match, move record */
				*val_pptr = val_ptr->next;
				val_ptr->next = NULL;
				_conf_hashtbl_insert(to_tbl, val_ptr);
				val_ptr = *val_pptr;
			}
		}
	}
}

void s_p_hashtbl_merge_override(s_p_hashtbl_t *to_tbl,
				s_p_hashtbl_t *from_tbl)
{
	int i;
	s_p_values_t **val_pptr, *val_ptr, *match_ptr;

	if (!to_tbl || !from_tbl)
		return;

	for (i = 0; i < CONF_HASH_LEN; i++) {
		val_pptr = &from_tbl->hash[i];
		val_ptr = from_tbl->hash[i];
		while (val_ptr) {
			if (val_ptr->data_count == 0) {
				/* No data in from_hashtbl record to move.
				 * Skip record */
				val_pptr = &val_ptr->next;
				val_ptr = val_ptr->next;
				continue;
			}
			match_ptr = _conf_hashtbl_lookup(to_tbl, val_ptr->key);
			if (match_ptr) {	/* Found matching key */
				_conf_hashtbl_swap_data(val_ptr, match_ptr);
				val_pptr = &val_ptr->next;
				val_ptr = val_ptr->next;
			} else {	/* No match, move record */
				*val_pptr = val_ptr->next;
				val_ptr->next = NULL;
				_conf_hashtbl_insert(to_tbl, val_ptr);
				val_ptr = *val_pptr;
			}
		}
	}
}

void s_p_hashtbl_merge_keys(s_p_hashtbl_t *to_tbl,
			    s_p_hashtbl_t *from_tbl)
{
	int i;
	_expline_values_t* f_expline;
	_expline_values_t* t_expline;
	s_p_values_t **pp, *p, *match_ptr;

	if (!to_tbl || !from_tbl)
		return;

	for (i = 0; i < CONF_HASH_LEN; i++) {
		pp = &from_tbl->hash[i];
		p = from_tbl->hash[i];
		while (p) {
			match_ptr = _conf_hashtbl_lookup(to_tbl, p->key);
			if (match_ptr) {	/* Found matching key */
				if (match_ptr->type == p->type &&
				    (p->type == S_P_LINE ||
				     p->type == S_P_EXPLINE)) {
					t_expline = (_expline_values_t*)
						    match_ptr->data;
					f_expline = (_expline_values_t*)
						    p->data;
					s_p_hashtbl_merge_keys(
							t_expline->template,
							f_expline->template);
					/* Keys merged, free container memory */
					s_p_hashtbl_destroy(f_expline->template);
					s_p_hashtbl_destroy(f_expline->index);
					//FIXME: Destroy "values" ?
					xfree(f_expline);
				}
				pp = &p->next;
				p = p->next;
			} else {	/* No match, move record */
				*pp = p->next;
				p->next = NULL;
				_conf_hashtbl_insert(to_tbl, p);
				p = *pp;
			}
		}
	}

}

int s_p_parse_line_complete(s_p_hashtbl_t *hashtbl,
			    const char* key, const char* value,
			    const char *line, char **leftover)
{
	if (!s_p_parse_pair(hashtbl, key, value)) {
		error("Error parsing '%s = %s', most left part of the"
		      " line: %s.", key, value, line);
		return SLURM_ERROR;
	}

	if (!s_p_parse_line(hashtbl, *leftover, leftover)) {
		error("Unable to parse line %s", *leftover);
		return SLURM_ERROR;
	}

	return SLURM_SUCCESS;
}

/*
 * custom handlers used by _parse_expline_adapt_table for config elements
 * expansions.
 */
static int _parse_line_expanded_handler(
		void **dest, slurm_parser_enum_t type,
		const char *key, const char *value,
		const char *line, char **leftover)
{
	*dest = hostlist_create(value);
	/* FIXME: this function should always return either an empty list, or
	 * the string as its first element if it was not expandable, or the
	 * list of strings expanded. So the only case where it returns null,
	 * is where there is no more enough memory to allocate the list, and
	 * it should be a crash cause.
	 */
	xassert(*dest);
	return 1;
}
static void _parse_line_expanded_destroyer(void* data)
{
	hostlist_destroy(data);
}

/*
 * convert every s_p_values_t to an S_P_POINTER casted hostlist (except
 * S_P_PLAIN_STRING)
 * This will enable to generate the hostlists corresponding to all the config
 * elements in order to later map the various expanded master keys to their
 * corresponding config values.
 * S_P_PLAIN_STRING specifying not be considered as an expandable string
 * is thus just converted to a real S_P_STRING and not an hostlist.
 */
static s_p_hashtbl_t *_parse_expline_adapt_table(const s_p_hashtbl_t *tbl)
{
	s_p_hashtbl_t *to_tbl = xmalloc(sizeof(*to_tbl));

	xassert(tbl);

	for (int i = 0; i < CONF_HASH_LEN; ++i) {
		for (s_p_values_t *val_ptr = tbl->hash[i];
		     val_ptr; val_ptr = val_ptr->next) {
			s_p_values_t *val_copy = xmalloc(sizeof(*val_copy));
			val_copy->key = xstrdup(val_ptr->key);
			val_copy->operator = val_ptr->operator;
			if (val_ptr->type == S_P_PLAIN_STRING) {
				val_copy->type = S_P_STRING;
			} else {
				val_copy->type = S_P_POINTER;
				val_copy->handler =
					_parse_line_expanded_handler;
				val_copy->destroy =
					_parse_line_expanded_destroyer;
			}
			_conf_hashtbl_insert(to_tbl, val_copy);
		}
	}

	/*
	 * We cannot copy a regex since a regfree() on either
	 * the original or the copy can affect the other one.
	 */
	if (regcomp(&to_tbl->keyvalue_re, keyvalue_pattern, REG_EXTENDED))
		fatal("keyvalue regex compilation failed");

	return to_tbl;
}

/*
 * walk down a tree of s_p_values_t converting every S_P_PLAIN_STRING
 * element to an S_P_STRING element.
 */
static void _hashtbl_plain_to_string(s_p_hashtbl_t *tbl)
{
	_expline_values_t* v_data;
	s_p_values_t *p;
	int i, j;

	xassert(tbl);

	for (i = 0; i < CONF_HASH_LEN; ++i) {
		for (p = tbl->hash[i]; p; p = p->next) {
			if (p->type == S_P_PLAIN_STRING) {
				p->type = S_P_STRING;
			} else if (p->type == S_P_LINE
					|| p->type == S_P_EXPLINE) {
				v_data = (_expline_values_t*)p->data;
				for (j = 0; j < p->data_count; ++j) {
					_hashtbl_plain_to_string(
							v_data->values[j]);
				}
			}
		}
	}
}

/*
 * associate a particular config element to a set of tables corresponding
 * to the expanded master keys associated.
 * The config element is either an S_P_STRING or an hostlist inside an
 * S_P_POINTER as transformed in _parse_expline_adapt_table.
 * In case the config element to process is an hostlist, the number of elements
 * must match the number of master keys otherwise an error is returned.
 * The config elements are mapped to their original S_P_* type when associated
 * with the tables using s_p_parse_pair().
 */
static int _parse_expline_doexpand(s_p_hashtbl_t** tables,
				   int tables_count,
				   s_p_values_t* item)
{
	hostlist_t *item_hl, *sub_item_hl;
	int item_count, i;
	int j, items_per_record, items_idx = 0;
	char* item_str = NULL;

	xassert(item);

	if (!item->data) {
		/* nothing to expand, a line may not have a key specified */
		return 1;
	}

	/* a plain string in the original s_p_options_t,
	 * copy the string as it using s_p_parse_pair() */
	if (item->type == S_P_STRING) {
		for (i = 0; i < tables_count; ++i) {
			if (!s_p_parse_pair(tables[i],
					    item->key,
					    item->data)) {
				error("parsing %s=%s.",
				      item->key, (char*)item->data);
				return 0;
			}
		}
		return 1;
	}

	/*
	 * Not a plain string in the original s_p_options_t, a temporary
	 * hostlist has been generated, parse each expanded value using
	 * s_p_parse_pair() mapping it to the right master key table.
	 *
	 * If the number of expanded value is less than the number of
	 * key tables, cycle around the expanded value in order to
	 * feed all the requested key tables (entities) with a value.
	 *
	 * If the number of expanded value m is greater than the number
	 * of key tables n (entities) and (m mod(n)) is zero, then split the
	 * set of expanded values in n consecutive sets (strings).
	 */
	item_hl = item->data;
	item_count = hostlist_count(item_hl);
	if ((item_count < tables_count) || (item_count == 1)) {
		items_per_record = 1;
	} else if ((item_count >= tables_count) &&
		   ((item_count % tables_count) == 0)) {
		items_per_record = (int) (item_count / tables_count);
	} else {
		item_str = hostlist_ranged_string_xmalloc(item_hl);
		error("parsing %s=%s : count is not coherent with the"
		      " amount of records or there must be no more than"
		      " one (%d vs %d)", item->key, item_str,
		      item_count, tables_count);
		xfree(item_str);
		return 0;
	}

	for (i = 0; i < tables_count; ++i) {

		/* Extract the string representation of the proper value(s)
		 * from the expanded one (if not already done) */
		if (item_count > 1) {
			if (item_str)
				free(item_str);
			if (items_per_record > 1) {
				/* multiple items per table,
				 * extract the consecutive set for this table */
				item_str = hostlist_nth(item_hl, items_idx++);
				sub_item_hl = hostlist_create(item_str);
				for (j = 1; j < items_per_record; j++) {
					free(item_str);
					item_str = hostlist_nth(item_hl,
								items_idx++);
					hostlist_push_host(sub_item_hl,
							   item_str);
				}
				free(item_str);
				item_str = hostlist_ranged_string_malloc(
					sub_item_hl);
				hostlist_destroy(sub_item_hl);
			} else {
				/* one item per table,
				 * extract the right item for this table */
				item_str = hostlist_nth(item_hl, items_idx++);
			}
			if (items_idx >= item_count)
				items_idx = 0;
		} else if (item_count == 1) {
			/* only one item, extract it once for all */
			item_count--;
			item_str = hostlist_shift(item_hl);
		}

		/*
		 * The destination tables are created without any info on the
		 * operator associated with the key in s_p_parse_line_expanded.
		 * So, parse the targeted pair injecting that information to
		 * push it into the destination table.
		 */
		if (!s_p_parse_pair_with_op(tables[i], item->key, item_str,
					    item->operator)) {
			error("parsing %s=%s after expansion.", item->key,
			      item_str);
			free(item_str);
			return 0;
		}
	}

	if (item_str)
		free(item_str);
	return 1;
}

int s_p_parse_line_expanded(const s_p_hashtbl_t *hashtbl,
			    s_p_hashtbl_t*** data, int* data_count,
			    const char* key, const char* value,
			    const char *line, char **leftover)
{
	int i, status;
	s_p_hashtbl_t* strtbl = NULL;
	s_p_hashtbl_t** tables = NULL;
	int tables_count = 0;
	hostlist_t *value_hl = NULL;
	char* value_str = NULL;
	s_p_values_t* attr = NULL;

	status = SLURM_ERROR;

	/* create the adapted temporary hash table used for expansion */
	strtbl = _parse_expline_adapt_table(hashtbl);
	xassert(strtbl);

	/* create hostlist and one iterator over it, since we will walk
	 * through the list for each new attribute to create final expanded
	 * hashtables.
	 */
	value_hl = hostlist_create(value);
	xassert(value_hl);
	*data_count = tables_count = hostlist_count(value_hl);

	/* populate the temporary expansion hash table, it will map the
	 * different config elements to either an hostlist (through S_P_POINTER) or
	 * to an S_P_STRING (for original element of type S_P_PLAIN_STRING) */
	if (!s_p_parse_line(strtbl, *leftover, leftover)) {
		error("Unable to parse line %s", *leftover);
		goto cleanup;
	}

	/* create the hash tables of the various master keys to expand and
	 * store the first main key=value pair for each one of them.
	 *
	 * The hash tables will be used to later map the config elements
	 * from the expanded attributes to have something like :
	 * [{key: value , attr1: val1.1, attr2: val2.1},
	 *  {key: value2, attr1: val1.2, attr2: val2.2}
	 * ]
	 */
	tables = xcalloc(tables_count, sizeof(s_p_hashtbl_t *));
	for (i = 0; i < tables_count; i++) {
		free(value_str);
		value_str = hostlist_shift(value_hl);
		tables[i] = _hashtbl_copy_keys(hashtbl);
		_hashtbl_plain_to_string(tables[i]);
		if (!s_p_parse_pair(tables[i], key, value_str)) {
			error("Error parsing '%s = %s', most left part of the"
			      " line: %s.", key, value_str, line);
			goto cleanup;
		}
	}

	/* convert each expanded values back to its original hash table, with
	 * conversions and handlers. This is done at the same time as storing
	 * the parsed attribute values with s_p_parse_pair */
	for (i = 0; i < CONF_HASH_LEN; ++i) {
		for (attr = strtbl->hash[i]; attr; attr = attr->next) {
			if (!_parse_expline_doexpand(tables,
						     tables_count,
						     attr)) {
				goto cleanup;
			}
		}
	}

	status = SLURM_SUCCESS;

cleanup:
	if (value_str)
		free(value_str);
	FREE_NULL_HOSTLIST(value_hl);
	s_p_hashtbl_destroy(strtbl);

	if (status == SLURM_ERROR && tables) {
		for (i = 0; i < tables_count; i++)
			if (tables[i])
				s_p_hashtbl_destroy(tables[i]);
		xfree(tables);
	}
	else {
		*data = tables;
	}

	return status;
}

/*
 * Returns 1 if the line is parsed cleanly, and 0 otherwise.
 * Set the operator of the targeted s_p_values_t to the provided value.
 */
int s_p_parse_pair_with_op(s_p_hashtbl_t *hashtbl, const char *key,
			   const char *value, slurm_parser_operator_t opt)
{
	s_p_values_t *p;
	char *leftover, *v;

	if ((p = _conf_hashtbl_lookup(hashtbl, key)) == NULL) {
		error("%s: Parsing error at unrecognized key: %s",
		      __func__, key);
		errno = EINVAL;
		return 0;
	}
	if (!value) {
		error("%s: Value pointer is NULL for key %s", __func__, key);
		errno = EINVAL;
		return 0;
	}
	p-> operator = opt;
	/* we have value separated from key here so parse it different way */
	while (*value != '\0' && isspace(*value))
		value++; /* skip spaces at start if any */
	if (*value == '"') { /* quoted value */
		v = (char *)value + 1;
		leftover = strchr(v, '"');
		if (leftover == NULL) {
			error("Parse error in data for key %s: %s", key, value);
			errno = EINVAL;
			return 0;
		}
	} else { /* unquoted value */
		leftover = v = (char *)value;
		while (*leftover != '\0' && !isspace(*leftover))
			leftover++;
	}
	value = xstrndup(v, leftover - v);
	if (*leftover != '\0')
		leftover++;
	while (*leftover != '\0' && isspace(*leftover))
		leftover++; /* skip trailing spaces */
	if (_handle_keyvalue_match(p, value, leftover, &leftover) == -1) {
		xfree(value);
		errno = EINVAL;
		return 0;
	}
	xfree(value);

	return 1;
}

/*
 * Returns 1 if the line is parsed cleanly, and 0 otherwise.
 */
int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value)
{
	return s_p_parse_pair_with_op(hashtbl, key, value, S_P_OPERATOR_SET);
}

/* common checks for s_p_get_* returns NULL if invalid.
 *
 * Information concerning these function can be found in the header file.
 */
static s_p_values_t* _get_check(slurm_parser_enum_t type,
				const char* key, const s_p_hashtbl_t* hashtbl)
{
	s_p_values_t *p;
	if (!hashtbl)
		return NULL;
	p = _conf_hashtbl_lookup(hashtbl, key);
	if (p == NULL) {
		error("Invalid key \"%s\"", key);
		return NULL;
	}
	if (p->type != type) {
		error("Key \"%s\" is not typed correctly", key);
		return NULL;
	}
	if (p->data_count == 0) {
		return NULL;
	}
	return p;
}

int s_p_get_string(char **str, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_STRING, key, hashtbl);

	if (p) {
		*str = xstrdup((char *)p->data);
		return 1;
	}

	return 0;
}

int s_p_get_long(long *num, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_LONG, key, hashtbl);

	if (p) {
		*num = *(long *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_uint16(uint16_t *num, const char *key,
		   const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_UINT16, key, hashtbl);

	if (p) {
		*num = *(uint16_t *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_uint32(uint32_t *num, const char *key,
		   const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_UINT32, key, hashtbl);

	if (p) {
		*num = *(uint32_t *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_uint64(uint64_t *num, const char *key,
		   const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_UINT64, key, hashtbl);

	if (p) {
		*num = *(uint64_t *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_operator(slurm_parser_operator_t *opt, 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) {
		*opt = p->operator;
		return 1;
	}
	error("Invalid key \"%s\"", key);
	return 0;
}

int s_p_get_pointer(void **ptr, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_POINTER, key, hashtbl);

	if (p) {
		*ptr = p->data;
		return 1;
	}

	return 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 = _get_check(S_P_ARRAY, key, hashtbl);

	if (p) {
		*ptr_array = (void **)p->data;
		*count = p->data_count;
		return 1;
	}

	return 0;
}

int s_p_get_line(s_p_hashtbl_t **ptr_array[], int *count,
		 const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_LINE, key, hashtbl);

	if (p) {
		*ptr_array = ((_expline_values_t*)p->data)->values;
		*count = p->data_count;
		return 1;
	}

	return 0;
}

int s_p_get_expline(s_p_hashtbl_t **ptr_array[], int *count,
		    const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_EXPLINE, key, hashtbl);

	if (p) {
		*ptr_array = ((_expline_values_t*)p->data)->values;
		*count = p->data_count;
		return 1;
	}

	return 0;
}

int s_p_get_boolean(bool *flag, const char *key, const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_BOOLEAN, key, hashtbl);

	if (p) {
		*flag = *(bool *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_float(float *num, const char *key,
		  const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_FLOAT, key, hashtbl);

	if (p) {
		*num = *(float *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_double(double *num, const char *key,
		  const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_DOUBLE, key, hashtbl);

	if (p) {
		*num = *(double *)p->data;
		return 1;
	}

	return 0;
}

int s_p_get_long_double(long double *num, const char *key,
			const s_p_hashtbl_t *hashtbl)
{
	s_p_values_t *p = _get_check(S_P_LONG_DOUBLE, key, hashtbl);

	if (p) {
		*num = *(long double *)p->data;
		return 1;
	}

	return 0;
}

/*
 * 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;
	uint64_t num64;
	float numf;
	double numd;
	long double numld;
	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:
		case S_P_PLAIN_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_UINT64:
			if (s_p_get_uint64(&num64, op->key, hashtbl))
				verbose("%s = %"PRIu64"", op->key, num64);
			else
				verbose("%s", op->key);
			break;
		case S_P_POINTER:
			if (s_p_get_pointer(&ptr, op->key, hashtbl))
				verbose("%s = %zx", op->key, (size_t)ptr);
			else
				verbose("%s", op->key);
			break;
		case S_P_LINE:
			if (s_p_get_line((s_p_hashtbl_t***)&ptr_array,
					 &count, op->key, hashtbl)) {
				verbose("%s, count = %d", op->key, count);
			} else {
				verbose("%s", op->key);
			}
			break;
		case S_P_EXPLINE:
			if (s_p_get_expline((s_p_hashtbl_t***)&ptr_array,
					    &count, op->key, hashtbl)) {
				verbose("%s, count = %d", op->key, count);
			} 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_FLOAT:
			if (s_p_get_float(&numf, op->key, hashtbl))
				verbose("%s = %f", op->key, numf);
			else
				verbose("%s", op->key);
			break;
		case S_P_DOUBLE:
			if (s_p_get_double(&numd, op->key, hashtbl))
				verbose("%s = %f", op->key, numd);
			else
				verbose("%s", op->key);
			break;
		case S_P_LONG_DOUBLE:
			if (s_p_get_long_double(&numld, op->key, hashtbl))
				verbose("%s = %Lf", op->key, numld);
			else
				verbose("%s", op->key);
			break;
		case S_P_IGNORE:
			break;
		}
	}
}

/*
 * Given an "options" array, pack the key, type of options along with values and
 * op of the hashtbl.
 *
 * Primarily for sending a table across the network so you don't have to read a
 * file in.
 */
extern buf_t *s_p_pack_hashtbl(const s_p_hashtbl_t *hashtbl,
			       const s_p_options_t options[],
			       const uint32_t cnt)
{
	buf_t *buffer = init_buf(0);
	s_p_values_t *p;
	int i;

	xassert(hashtbl);

	pack32(cnt, buffer);

	for (i = 0; i < cnt; i++) {
		p = _conf_hashtbl_lookup(hashtbl, options[i].key);

		xassert(p);

		pack16((uint16_t)options[i].type, buffer);
		packstr(options[i].key, buffer);

		pack16((uint16_t)p->operator, buffer);
		pack32((uint32_t)p->data_count, buffer);

		if (!p->data_count)
			continue;

		switch (options[i].type) {
		case S_P_ARRAY:
			if (options[i].pack) {
				pack32(p->data_count, buffer);
				void **ptr_array = (void **)p->data;
				for (int j = 0; j < p->data_count; j++) {
					options[i].pack(ptr_array[j], buffer);
				}
			}
			break;
		case S_P_STRING:
		case S_P_PLAIN_STRING:
			packstr((char *)p->data, buffer);
			break;
		case S_P_UINT32:
		case S_P_LONG:
			pack32(*(uint32_t *)p->data, buffer);
			break;
		case S_P_UINT16:
			pack16(*(uint16_t *)p->data, buffer);
			break;
		case S_P_UINT64:
			pack64(*(uint64_t *)p->data, buffer);
			break;
		case S_P_BOOLEAN:
			packbool(*(bool *)p->data, buffer);
			break;
		case S_P_FLOAT:
			packfloat(*(float *)p->data, buffer);
			break;
		case S_P_DOUBLE:
			packdouble(*(double *)p->data, buffer);
			break;
		case S_P_LONG_DOUBLE:
			packlongdouble(*(long double *)p->data, buffer);
			break;
		case S_P_IGNORE:
			break;
		default:
			fatal("%s: unsupported pack type %d",
			      __func__, options[i].type);
			break;
		}
	}

	return buffer;
}

/*
 * Given a buffer, unpack key, type, op and value into a hashtbl.
 */
extern s_p_hashtbl_t *s_p_unpack_hashtbl_full(buf_t *buffer,
					      const s_p_options_t options[])
{
	s_p_values_t *value = NULL;
	s_p_hashtbl_t *hashtbl = NULL;
	int i;
	bool bool_tmp;
	uint16_t uint16_tmp;
	uint32_t cnt, uint32_tmp;
	uint64_t uint64_tmp;
	float float_tmp;
	double double_tmp;
	long double ldouble_tmp;
	char *tmp_char;

	safe_unpack32(&cnt, buffer);

	hashtbl = xmalloc(sizeof(*hashtbl));

	for (i = 0; i < cnt; i++) {
		value = xmalloc(sizeof(s_p_values_t));

		safe_unpack16(&uint16_tmp, buffer);
		value->type = uint16_tmp;
		safe_unpackstr(&value->key, buffer);
		safe_unpack16(&uint16_tmp, buffer);
		value->operator = uint16_tmp;
		safe_unpack32(&uint32_tmp, buffer);
		value->data_count = uint32_tmp;

		_conf_hashtbl_insert(hashtbl, value);

		if (!value->data_count)
			continue;

		switch (value->type) {
		case S_P_ARRAY:
			xassert(options);
			if (options[i].unpack) {
				void **ptr_array;
				safe_unpack32(&uint32_tmp, buffer);
				value->data_count = uint32_tmp;
				value->data = xcalloc(value->data_count,
						      sizeof(void *));
				ptr_array = (void **)value->data;
				for (int j = 0; j < value->data_count; j++) {
					ptr_array[j] =
						options[i].unpack(buffer);
				}
			}
			break;
		case S_P_STRING:
		case S_P_PLAIN_STRING:
			safe_unpackstr(&tmp_char, buffer);
			value->data = tmp_char;
			break;
		case S_P_UINT32:
			safe_unpack32(&uint32_tmp, buffer);
			value->data = xmalloc(sizeof(uint32_t));
			*(uint32_t *)value->data = uint32_tmp;
			break;
		case S_P_LONG:
			safe_unpack32(&uint32_tmp, buffer);
			value->data = xmalloc(sizeof(long));
			*(long *)value->data = (long)uint32_tmp;
			break;
		case S_P_UINT16:
			safe_unpack16(&uint16_tmp, buffer);
			value->data = xmalloc(sizeof(uint16_t));
			*(uint16_t *)value->data = uint16_tmp;
			break;
		case S_P_UINT64:
			safe_unpack64(&uint64_tmp, buffer);
			value->data = xmalloc(sizeof(uint64_t));
			*(uint64_t *)value->data = uint64_tmp;
			break;
		case S_P_BOOLEAN:
			safe_unpackbool(&bool_tmp, buffer);
			value->data = xmalloc(sizeof(bool));
			*(bool *)value->data = bool_tmp;
			break;
		case S_P_FLOAT:
			safe_unpackfloat(&float_tmp, buffer);
			value->data = xmalloc(sizeof(float));
			*(float *)value->data = float_tmp;
			break;
		case S_P_DOUBLE:
			safe_unpackdouble(&double_tmp, buffer);
			value->data = xmalloc(sizeof(double));
			*(double *)value->data = double_tmp;
			break;
		case S_P_LONG_DOUBLE:
			safe_unpacklongdouble(&ldouble_tmp, buffer);
			value->data = xmalloc(sizeof(long double));
			*(long double *)value->data = ldouble_tmp;
			break;
		case S_P_IGNORE:
			break;
		default:
			fatal("%s: unsupported pack type %d",
			      __func__, value->type);
			break;
		}
	}

	return hashtbl;
unpack_error:
	s_p_hashtbl_destroy(hashtbl);
	error("%s: failed", __func__);
	return NULL;
}

extern s_p_hashtbl_t *s_p_unpack_hashtbl(buf_t *buffer)
{
	return s_p_unpack_hashtbl_full(buffer, NULL);
}

extern void transfer_s_p_options(s_p_options_t **full_options,
				 s_p_options_t *options,
				 int *full_options_cnt)
{
	s_p_options_t *full_options_ptr;
	int cnt = *full_options_cnt;

	xassert(full_options);

	for (s_p_options_t *op = options; op->key; op++, cnt++) {
		xrecalloc(*full_options, cnt + 1, sizeof(s_p_options_t));
		full_options_ptr = &(*full_options)[cnt];
		memcpy(full_options_ptr, op, sizeof(s_p_options_t));
		full_options_ptr->key = xstrdup(op->key);
	}
	*full_options_cnt = cnt;
}
