|  | /***************************************************************************** | 
|  | *  parse_config.h - parse any slurm.conf-like configuration file | 
|  | * | 
|  | *  NOTE: when you see the prefix "s_p_", think "slurm parser". | 
|  | ***************************************************************************** | 
|  | *  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>. | 
|  | *  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. | 
|  | \*****************************************************************************/ | 
|  |  | 
|  | #ifndef _PARSE_CONFIG_H | 
|  | #define _PARSE_CONFIG_H | 
|  |  | 
|  | #include <stdint.h> | 
|  | #include "slurm/slurm.h" | 
|  | #include "src/common/pack.h" | 
|  |  | 
|  | /* | 
|  | * This slurm file parser provides a method for parsing a file | 
|  | * for key-value pairs of the form "key = value".  This parser can be used | 
|  | * for any slurm-like configuration file, not just slurm.conf.  If you are | 
|  | * looking for code specific to slurm.conf, look in | 
|  | * src/common/slurm_conf.[hc]. | 
|  | * | 
|  | * In the parsed file, any amount of white-space is allowed between the | 
|  | * key, equal-sign, and value.  The parser handles comments, line | 
|  | * continuations, and escaped characters automatically.  Double-quotes can | 
|  | * be used to surround an entire value if white-space is needed within | 
|  | * a value string. | 
|  | * | 
|  | * A comment begins with a "#" and ends at the end of the line. A line | 
|  | * continuation is a "\" character at the end of the line (only white-space | 
|  | * may follow the "\").  A line continuation tells the parser to | 
|  | * concatenate the following line with the current line. | 
|  | * | 
|  | * To include a literal "\" or "#" character in a file, it can be escaped | 
|  | * by a preceding "\". | 
|  | * | 
|  | * Double-quotes CANNOT be escaped, and they must surround the entire value | 
|  | * string, they cannot be used within some substring of a value string. | 
|  | * An empty string can be specified with doubles quotes: Apple="". | 
|  | * | 
|  | * To use this parser, first construct an array of s_p_options_t structures. | 
|  | * Only the "key" string needs to be non-zero.  Zero or NULL are valid | 
|  | * defaults for type, handler, and destroy, which conveniently allows | 
|  | * then to be left out in any static initializations of options arrays. For | 
|  | * instance: | 
|  | * | 
|  | *	s_p_options_t options[] = {{"Apples", S_P_UINT16}, | 
|  | *	                           {"Oranges"}, | 
|  | *	                           {NULL}}; | 
|  | * | 
|  | * In this example, the handler and destroy functions for the "Apples" key | 
|  | * are NULL pointers, and for key "Oranges" even the type is zero.  A zero | 
|  | * type is equivalent to specifying type S_P_IGNORE. | 
|  | * | 
|  | * Once an s_p_options_t array is defined, it is converted into a slurm | 
|  | * parser hash table structure with the s_p_hashtbl_create() function. | 
|  | * The s_p_hashtbl_t thus returned can be given to the s_p_parse_file() | 
|  | * function to parse a file, and fill in the s_p_hashtbl_t structure with | 
|  | * the values found in the file.  Values for keys can then be retrieved | 
|  | * from the s_p_hashtbl_t with the functions with names beginning with | 
|  | * "s_p_get_", e.g. s_p_get_boolean(), s_p_get_string(), s_p_get_uint16(), | 
|  | * etc. | 
|  | * | 
|  | * Valid types | 
|  | * ----------- | 
|  | * | 
|  | * S_P_IGNORE - Any instance of specified key and associated value in a file | 
|  | *	will be allowed, but the value will not be stored and will not | 
|  | *	be retirevable from the s_p_hashtbl_t. | 
|  | * S_P_STRING - The value for a given key will be saved in string form. no | 
|  | *      conversions will be performed on the value, unless it is used as a | 
|  | *      nested definition inside a S_P_EXPLINE definition. (see S_P_EXPLINE) | 
|  | * S_P_PLAIN_STRING - The value for a given key will be saved in string form, | 
|  | *      no conversions will be performed on the value. | 
|  | * S_P_LONG - The value for a given key must be a valid | 
|  | *	string representation of a long integer (as determined by strtol()), | 
|  | *	otherwise an error will be raised. | 
|  | * S_P_UINT16 - The value for a given key must be a valid | 
|  | *	string representation of an unsigned 16-bit integer. | 
|  | * S_P_UINT32 - The value for a given key must be be a valid | 
|  | *	string representation of an unsigned 32-bit integer. | 
|  | * S_P_UINT64 - The value for a given key must be be a valid | 
|  | *	string representation of an unsigned 64-bit integer. | 
|  | * S_P_POINTER - The parser makes no assumption about the type of the value. | 
|  | *    	The s_p_get_pointer() function will return a pointer to the | 
|  | *	s_p_hashtbl_t's internal copy of the value.  By default, the value | 
|  | *	will simply be the string representation of the value found in the file. | 
|  | *	This differs from S_P_STRING in that s_p_get_string() returns a COPY | 
|  | *	of the value which must be xfree'ed by the user.  The pointer | 
|  | *	returns by s_p_get_pointer() must NOT be freed by the user. | 
|  | *  	It is intended that normally S_P_POINTER with be used in conjunction | 
|  | *	with "handler" and "destroy" functions to implement a custom type. | 
|  | * S_P_ARRAY - This (and S_P_IGNORE, which does not record the fact that it | 
|  | *	has seen the key previously) is the only type which allows its key to | 
|  | * 	appear multiple times in a file.  With any other type (except | 
|  | *	S_P_IGNORE), an error will be raised when a key is seen more than | 
|  | *	once in a file. | 
|  | *	S_P_ARRAY works mostly the same as S_P_POINTER, except that it builds | 
|  | *	an array of pointers to the found values. | 
|  | * S_P_LINE - This type avoids to write custom handlers by directly providing | 
|  | *      the capability to express nested s_p_options_t structs into an | 
|  | *      s_p_options_t. As with S_P_ARRAY, it allows its key to appear multiple | 
|  | *      times in a file. | 
|  | *      It can be seen as an advanced version of the S_P_ARRAY type enabling | 
|  | *      to return an array of s_p_hashtable_t containing the sub-elements as | 
|  | *      described in the nested s_p_options_t. | 
|  | *      No custom handlers are supported with S_P_LINE. An example of S_P_LINE | 
|  | *      usage would be : | 
|  | *      s_p_options_t entity_options[] = { | 
|  | *         {"Entity", S_P_STRING} | 
|  | *         {"CoordX", S_P_UINT32}, | 
|  | *         {"CoordY", S_P_UINT32}, | 
|  | *         {"CoordZ", S_P_UINT32}, | 
|  | *         {NULL} | 
|  | *      }; | 
|  | *      s_p_options_t options[] = { | 
|  | *         {"Entity", S_P_LINE, NULL, NULL, entity_options}, | 
|  | *         {NULL} | 
|  | *      }; | 
|  | *      The s_p_get_line() function will return the array of hashtables | 
|  | *      corresponding to the "Entity" entries found in the configuration file. | 
|  | *      Note that "Entity=%key% ..." lines sharing the same master "key" | 
|  | *      will be automatically merged into the same hashtable enabling to split | 
|  | *      the definition over multiple lines without having to use the '\' | 
|  | *      delimiter. | 
|  | *      The following example shows the content the previously defined | 
|  | *      s_p_options_t would handle : | 
|  | *      ----- | 
|  | *      Entity=node[0-3] CoordX=0 | 
|  | *      Entity=node[0-3] CoordY=2 | 
|  | *      Entity=node[4-7] CoordX=1 | 
|  | *      Entity=node[4-7] CoordY=2 | 
|  | *      ----- | 
|  | *      This file would provide a hashtables array containing 2 elements with | 
|  | *      the following master keys : | 
|  | *      - node[0-3] | 
|  | *      - node[4-7] | 
|  | *      /!\ WARNING: do not specify the same struct as suboption or /!\ | 
|  | *      /!\ an infinite loop will occur.                            /!\ | 
|  | * * S_P_EXPLINE - This type is an extended version of the S_P_LINE type that | 
|  | *      add the capability to expand the hostlist formatted elements when | 
|  | *      possible in order to reduce the number of lines required to parse some | 
|  | *      complex configurations. The values associated to the key of the | 
|  | *      S_P_EXPLINE will then be automatically expanded in order to return one | 
|  | *      hashtable element per associated value. | 
|  | *      Replacing the S_P_LINE with an S_P_EXPLINE in the previous example with : | 
|  | *      s_p_options_t options[] = { | 
|  | *         {"Entity", S_P_EXPLINE, NULL, NULL, entity_options}, | 
|  | *         {NULL} | 
|  | *      }; | 
|  | *      would then enable to automatically manage conf files like : | 
|  | *      ----- | 
|  | *      Entity=node[0-3] CoordX=0 | 
|  | *      Entity=node[0-3] CoordY=2 CoordZ=[10-13] | 
|  | *      Entity=node[4-7] CoordX=1 | 
|  | *      Entity=node[4-7] CoordY=2 CoordZ=[10-13] | 
|  | *      ----- | 
|  | *      The s_p_get_expline() function will in this example returns an array of | 
|  | *      eight elements, having the master key set to the following values : | 
|  | *      - node0 | 
|  | *      - node1 | 
|  | *      ... | 
|  | *      Note that in case a particular option string must not be expanded but | 
|  | *      still used within an S_P_EXPLINE definition, it will have to be | 
|  | *      expressed as a S_P_PLAIN_STRING instead of a basic S_P_STRING. Indeed, | 
|  | *      S_P_STRING are automatically expanded using hostlist related functions. | 
|  | *      An example of such a situation would be something like : | 
|  | *      s_p_options_t entity_options[] = { | 
|  | *         {"Entity", S_P_STRING} | 
|  | *         {"Enclosed", S_P_PLAIN_STRING}, | 
|  | *         {NULL} | 
|  | *      }; | 
|  | *      s_p_options_t options[] = { | 
|  | *         {"Entity", S_P_EXPLINE, NULL, NULL, entity_options}, | 
|  | *         {NULL} | 
|  | *      }; | 
|  | *      ----- | 
|  | *      Entity=switch[0-1] Enclosed=flake[0-17] | 
|  | *      Entity=switch[2-3] Enclosed=flake[18-35] | 
|  | *      ----- | 
|  | *      /!\ WARNING: do not specify the same struct as suboption or /!\ | 
|  | *      /!\ an infinite loop will occur.                            /!\ | 
|  | * | 
|  | * Handlers and destructors | 
|  | * ------------------------ | 
|  | * | 
|  | * Any key specified in an s_p_options_t array can have function callbacks for | 
|  | * a "handler" function and a "destroy" function.  The prototypes for each | 
|  | * are available below in the typedef of s_p_options_t. | 
|  | * | 
|  | * The "handler" function is given the "key" string, "value" string, and a | 
|  | * pointer to the remainder of the "line" on which the key-value pair was found | 
|  | * (this is the line after the parser has removed comments and concatenated | 
|  | * continued lines).  The handler can transform the value any way it desires, | 
|  | * and then return a pointer to the newly allocated value data in the "data" | 
|  | * pointer.  The handler shall also return int the "leftover" parameter a | 
|  | * pointer into the "line" buffer designating the start of any leftover, | 
|  | * unparsed characters in the string.  The return code from "handler" must be | 
|  | * -1 if the value is invalid, 0 if the value is valid but no value will be set | 
|  | * for "data" (the parser will not flag this key as already seen, and the | 
|  | * destroy() function will not be called during s_p_hashtbl_destroy()), | 
|  | * and 1 if "data" is set. | 
|  | * | 
|  | * If the "destroy" function is set for a key, and the parser will mark the key | 
|  | * as "seen" during parsing, then it will pass the pointer to the value data | 
|  | * to the "destroy" function when s_p_hashtbl_destroy() is called.  If | 
|  | * a key was "seen" during parsing, but the "destroy" function is NULL, | 
|  | * s_p_hashtbl_destroy() will call xfree() on the data pointer. | 
|  | */ | 
|  |  | 
|  | typedef struct s_p_values s_p_values_t; | 
|  | typedef struct s_p_hashtbl s_p_hashtbl_t; | 
|  |  | 
|  | typedef enum slurm_parser_enum { | 
|  | S_P_IGNORE = 0, | 
|  | S_P_STRING, | 
|  | S_P_LONG, | 
|  | S_P_UINT16, | 
|  | S_P_UINT32, | 
|  | S_P_UINT64, | 
|  | S_P_POINTER, | 
|  | S_P_ARRAY, | 
|  | S_P_BOOLEAN, | 
|  | S_P_LINE, | 
|  | S_P_EXPLINE, | 
|  | S_P_PLAIN_STRING /* useful only within S_P_EXPLINE */, | 
|  | S_P_FLOAT, | 
|  | S_P_DOUBLE, | 
|  | S_P_LONG_DOUBLE | 
|  |  | 
|  | } slurm_parser_enum_t; | 
|  |  | 
|  | /* | 
|  | * Standard Slurm conf files use key=value elements. | 
|  | * slurm_parser_operator_t extends that concept to cover additional | 
|  | * use cases like : | 
|  | *        key+=value | 
|  | *        key-=value | 
|  | *        key*=value | 
|  | *        key/=value | 
|  | * | 
|  | * this feature is for now dedicated to the layouts framework. It enables | 
|  | * to have advanced modifications of entities reusing the traditional | 
|  | * Slurm parser with the new operator information to manage updates. | 
|  | * | 
|  | */ | 
|  | typedef enum slurm_parser_operator { | 
|  | S_P_OPERATOR_SET = 0, | 
|  | S_P_OPERATOR_ADD, | 
|  | S_P_OPERATOR_SUB, | 
|  | S_P_OPERATOR_MUL, | 
|  | S_P_OPERATOR_DIV, | 
|  | S_P_OPERATOR_SET_IF_MIN, | 
|  | S_P_OPERATOR_SET_IF_MAX, | 
|  | S_P_OPERATOR_AVG | 
|  | } slurm_parser_operator_t; | 
|  |  | 
|  | typedef struct conf_file_options { | 
|  | char *key; | 
|  | slurm_parser_enum_t type; | 
|  | int (*handler)(void **data, slurm_parser_enum_t type, | 
|  | const char *key, const char *value, | 
|  | const char *line, char **leftover); | 
|  | void (*destroy)(void *data); | 
|  | struct conf_file_options* line_options; | 
|  | void (*pack)(void *data, buf_t *buffer); | 
|  | void *(*unpack)(buf_t *buffer); | 
|  | } s_p_options_t; | 
|  |  | 
|  |  | 
|  | s_p_hashtbl_t *s_p_hashtbl_create_cnt(const struct conf_file_options options[], | 
|  | int *cnt); | 
|  | s_p_hashtbl_t *s_p_hashtbl_create(const struct conf_file_options options[]); | 
|  | void s_p_hashtbl_destroy(s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* Returns SLURM_SUCCESS if file was opened and parse correctly | 
|  | * OUT hash_val - cyclic redundancy check (CRC) character-wise value | 
|  | *                of file. | 
|  | * IN flags - flags affecting behavior. | 
|  | * OUT last_ancestor - last ancestor configuration filename used to map nested | 
|  | * 		       Include files in configless configurations. | 
|  | */ | 
|  | int s_p_parse_file(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, char *filename, | 
|  | uint32_t flags, char *last_ancestor); | 
|  |  | 
|  | /* Returns SLURM_SUCCESS if buffer was opened and parse correctly. | 
|  | * buffer must be a valid buf_t buffer only containing strings. The parsing | 
|  | * stops at the first non string content extracted. | 
|  | * OUT hash_val - cyclic redundancy check (CRC) character-wise value | 
|  | *                of file. | 
|  | * IN ignore_new - do not treat unrecognized keywords as a fatal error, | 
|  | *                 print debug() message and continue | 
|  | */ | 
|  | int s_p_parse_buffer(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, | 
|  | buf_t *buffer, bool ignore_new); | 
|  |  | 
|  | /* | 
|  | * 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); | 
|  |  | 
|  | /* | 
|  | * Returns 1 if the line is parsed cleanly, and 0 otherwise. | 
|  | * Set the operator of the updated s_p_values_t to the provided one. | 
|  | */ | 
|  | int s_p_parse_pair_with_op(s_p_hashtbl_t *hashtbl, const char *key, | 
|  | const char *value, slurm_parser_operator_t opt); | 
|  |  | 
|  | /* | 
|  | * 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); | 
|  |  | 
|  | /* | 
|  | * 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 old default values while adding new defaults. | 
|  | * | 
|  | * IN from_hashtbl - Source of old data | 
|  | * IN to_hashtbl - Destination for old data (if new value not already set) | 
|  | */ | 
|  | void s_p_hashtbl_merge(s_p_hashtbl_t *to_hashtbl, s_p_hashtbl_t *from_hashtbl); | 
|  |  | 
|  | /* Like s_p_hashtbl_merge, but if for a key, data exists in both tables, data | 
|  | * is swapped. | 
|  | */ | 
|  | void s_p_hashtbl_merge_override(s_p_hashtbl_t *to_hashtbl, | 
|  | s_p_hashtbl_t *from_hashtbl); | 
|  |  | 
|  | /* | 
|  | * Mainly to enable a generic set of option to be merged with a specific set | 
|  | * of options. | 
|  | */ | 
|  | void s_p_hashtbl_merge_keys(s_p_hashtbl_t *to_hashtbl, | 
|  | s_p_hashtbl_t *from_hashtbl); | 
|  |  | 
|  | int s_p_parse_line_complete(s_p_hashtbl_t *hashtbl, | 
|  | const char* key, const char* value, | 
|  | const char *line, char **leftover); | 
|  |  | 
|  | /* | 
|  | * s_p_parse_line_expanded | 
|  | * | 
|  | * Parse a whole line of data and generate an array of s_p_hashtable. This | 
|  | * function is meant to be used inside a custom handler of a (left most) key. | 
|  | * | 
|  | * This function can be used in a custom handler, but in general, use of | 
|  | * S_P_*LINE is preferred. | 
|  | * | 
|  | * IN hashtbl - hash table template of a final line after expansion, | 
|  | *		types and custom handlers are used after line has been | 
|  | *		expanded. They will parse values as if the line were not | 
|  | *		expandable and were written only with one value by key. | 
|  | *		This hash table must contains the master key definition | 
|  | *		(left most key of the line). | 
|  | * OUT data - resulting hashtables array | 
|  | * OUT data_count - number of resulting hashtables in the array | 
|  | * IN key - the master key (left most key of the line) | 
|  | * IN value - the value attached to the master key (which will be converted | 
|  | *	      with s_p_parse_pair thanks to hashtbl) | 
|  | * IN line - only used for logging | 
|  | * IN leftover - used by s_p_parse_line | 
|  | */ | 
|  | 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); | 
|  |  | 
|  | /* | 
|  | * 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 returned in "str". | 
|  | * | 
|  | * OUT str - pointer to a copy of the string value | 
|  | *           (caller is responsible 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_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 returned 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_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 returned 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_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 returned 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_get_uint64 | 
|  | * | 
|  | * Search for a key in a s_p_hashtbl_t with value of type | 
|  | * uint64.  If the key is found and has a set value, the | 
|  | * value is returned in "num". | 
|  | * | 
|  | * OUT num - pointer to a uint64_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_uint64(uint64_t *num, const char *key, | 
|  | const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * s_p_get_float | 
|  | * | 
|  | * Search for a key in a s_p_hashtbl_t with value of type | 
|  | * float.  If the key is found and has a set value, the | 
|  | * value is returned in "num". | 
|  | * | 
|  | * OUT num - pointer to a float 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_float(float *num, const char *key, | 
|  | const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * s_p_get_double | 
|  | * | 
|  | * Search for a key in a s_p_hashtbl_t with value of type | 
|  | * double.  If the key is found and has a set value, the | 
|  | * value is returned in "num". | 
|  | * | 
|  | * OUT num - pointer to a double 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_double(double *num, const char *key, | 
|  | const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * s_p_get_long_double | 
|  | * | 
|  | * Search for a key in a s_p_hashtbl_t with value of type | 
|  | * long double.  If the key is found and has a set value, the | 
|  | * value is returned in "num". | 
|  | * | 
|  | * OUT num - pointer to a long double 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_double(long double *num, const char *key, | 
|  | const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * s_p_get_operator | 
|  | * | 
|  | * Search for a key in a s_p_hashtbl_t and return the operator | 
|  | * associated with that key in the configuration file. The operator | 
|  | * is one of the slurm_parser_operator_t enum possible values. | 
|  | * | 
|  | * OUT operator - pointer to a slurm_parser_operator_t where the | 
|  | *     operator is returned | 
|  | * IN key - hash table key | 
|  | * IN hashtbl - hash table created by s_p_hashtbl_create() | 
|  | * | 
|  | * Returns 1 when a operator was set for "key" during parsing and | 
|  | *     "operator" was successfully set, otherwise returns 0; | 
|  | */ | 
|  | int s_p_get_operator(slurm_parser_operator_t *opt, const char *key, | 
|  | const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * 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 returned in "ptr". | 
|  | * | 
|  | * OUT num - 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_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 num - pointer to a void pointer-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_array(void **ptr_array[], int *count, | 
|  | const char *key, const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /** works like s_p_get_array but each item of the array is a s_p_hashtbl_t */ | 
|  | int s_p_get_line(s_p_hashtbl_t **ptr_array[], int *count, | 
|  | const char *key, const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /** works like s_p_get_array but each item of the array is a s_p_hashtbl_t */ | 
|  | int s_p_get_expline(s_p_hashtbl_t **ptr_array[], int *count, | 
|  | const char *key, const s_p_hashtbl_t *hashtbl); | 
|  |  | 
|  | /* | 
|  | * 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 returned 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); | 
|  |  | 
|  | /* | 
|  | * 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[]); | 
|  |  | 
|  |  | 
|  | /* | 
|  | * 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); | 
|  |  | 
|  | /* | 
|  | * 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[]); | 
|  | extern s_p_hashtbl_t *s_p_unpack_hashtbl(buf_t *buffer); | 
|  |  | 
|  | /* | 
|  | * copy options onto the end of full_options | 
|  | * IN/OUT full_options | 
|  | * IN options | 
|  | * IN/OUT full_options_cnt | 
|  | * | 
|  | * Used if the full set of options are not available from one location. | 
|  | */ | 
|  | extern void transfer_s_p_options(s_p_options_t **full_options, | 
|  | s_p_options_t *options, | 
|  | int *full_options_cnt); | 
|  |  | 
|  | #endif /* !_PARSE_CONFIG_H */ |